<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="keywords" content="imlgw,半岛铁盒,blog,Java博客,程序员,个人博客,java開發,程序員,個人博客,Java">
    <meta name="description" content="大悲无泪，大悟无言，大笑无声。">
    <meta name="author" content="Resolmi">
    
    <title>
        
            LeetCode回溯&amp;递归 |
        
        Tadow
    </title>
    
<link rel="stylesheet" href="/css/style.css">

    <link rel="shortcut icon" href="https://static.imlgw.top/blog/20210731/BtJz541CcmJU.ico">
    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/css/font-awesome.min.css">
    <script id="hexo-configurations">
    let KEEP = window.KEEP || {};
    KEEP.hexo_config = {"hostname":"imlgw.top","root":"/","language":"zh-CN","path":"search.json"};
    KEEP.theme_config = {"toc":{"enable":true,"number":true,"expand_all":true,"init_open":true},"style":{"primary_color":"#0066CC","avatar":"https://static.imlgw.top/blog/20210731/3C7hCSRR3lfq.png","favicon":"https://static.imlgw.top/blog/20210731/BtJz541CcmJU.ico","article_img_align":"left","left_side_width":"260px","content_max_width":"920px","hover":{"shadow":false,"scale":true},"first_screen":{"enable":true,"background_img":"/images/image.svg","description":"Keep It Simple & Stupid."},"scroll":{"progress_bar":{"enable":true},"percent":{"enable":true}}},"local_search":{"enable":true,"preload":false},"code_copy":{"enable":true,"style":"default"},"pjax":{"enable":true},"lazyload":{"enable":true},"version":"3.4.3"};
    KEEP.language_ago = {"second":"%s 秒前","minute":"%s 分钟前","hour":"%s 小时前","day":"%s 天前","week":"%s 周前","month":"%s 月前","year":"%s 年前"};
  </script>
<meta name="generator" content="Hexo 5.4.0"><link rel="stylesheet" href="/css/prism.css" type="text/css"></head>


<body>
<div class="progress-bar-container">
    
        <span class="scroll-progress-bar"></span>
    

    
        <span class="pjax-progress-bar"></span>
        <span class="pjax-progress-icon">
            <i class="fas fa-circle-notch fa-spin"></i>
        </span>
    
</div>


<main class="page-container">

    

    <div class="page-main-content">

        <div class="page-main-content-top">
            <header class="header-wrapper">

    <div class="header-content">
        <div class="left">
            
            <a class="logo-title" href="/">
                Tadow
            </a>
        </div>

        <div class="right">
            <div class="pc">
                <ul class="menu-list">
                    
                        <li class="menu-item">
                            <a class=""
                               href="/"
                            >
                                首页
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/archives"
                            >
                                归档
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/categories"
                            >
                                分类
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/sbe"
                            >
                                订阅
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/links"
                            >
                                友链
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/about"
                            >
                                关于
                            </a>
                        </li>
                    
                    
                        <li class="menu-item search search-popup-trigger">
                            <i class="fas fa-search"></i>
                        </li>
                    
                </ul>
            </div>
            <div class="mobile">
                
                    <div class="icon-item search search-popup-trigger"><i class="fas fa-search"></i></div>
                
                <div class="icon-item menu-bar">
                    <div class="menu-bar-middle"></div>
                </div>
            </div>
        </div>
    </div>

    <div class="header-drawer">
        <ul class="drawer-menu-list">
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/">首页</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/archives">归档</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/categories">分类</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/sbe">订阅</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/links">友链</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/about">关于</a>
                </li>
            
        </ul>
    </div>

    <div class="window-mask"></div>

</header>


        </div>

        <div class="page-main-content-middle">

            <div class="main-content">

                
                    <div class="fade-in-down-animation">
    <div class="article-content-container">

        <div class="article-title">
            <span class="title-hover-animation">LeetCode回溯&amp;递归</span>
        </div>

        
            <div class="article-header">
                <div class="avatar">
                    <img src="https://static.imlgw.top/blog/20210731/3C7hCSRR3lfq.png">
                </div>
                <div class="info">
                    <div class="author">
                        <span class="name">Resolmi</span>
                        
                            <span class="author-label">BOSS</span>
                        
                    </div>
                    <div class="meta-info">
                        <div class="article-meta-info">
    <span class="article-date article-meta-item">
        <i class="fas fa-edit"></i>&nbsp;2019-10-10 00:00:00
    </span>
    
        <span class="article-categories article-meta-item">
            <i class="fas fa-folder"></i>&nbsp;
            <ul>
                
                    <li>
                        <a href="/categories/%E7%AE%97%E6%B3%95/">算法</a>&nbsp;
                    </li>
                
            </ul>
        </span>
    
    
        <span class="article-tags article-meta-item">
            <i class="fas fa-tags"></i>&nbsp;
            <ul>
                
                    <li>
                        <a href="/tags/LeetCode/">LeetCode</a>&nbsp;
                    </li>
                
                    <li>
                        | <a href="/tags/%E5%9B%9E%E6%BA%AF/">回溯</a>&nbsp;
                    </li>
                
            </ul>
        </span>
    

    
    
        <span class="article-wordcount article-meta-item">
            <i class="fas fa-file-word"></i>&nbsp;<span>28k 字</span>
        </span>
    
    
        <span class="article-min2read article-meta-item">
            <i class="fas fa-clock"></i>&nbsp;<span>131 分钟</span>
        </span>
    
    
        <span class="article-pv article-meta-item">
            <i class="fas fa-eye"></i>&nbsp;<span id="busuanzi_value_page_pv"></span>
        </span>
    
</div>

                    </div>
                </div>
            </div>
        

        <div class="article-content markdown-body">
            <h2 id="17-电话号码的字母组合"><a href="#17-电话号码的字母组合" class="headerlink" title="17. 电话号码的字母组合"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/" >17. 电话号码的字母组合<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个仅包含数字 <code>2-9</code> 的字符串，返回所有它能表示的字母组合。</p>
<p>给出数字到字母的映射如下（与电话按键相同）注意 1 不对应任何字母</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/blog/20191012/Ro4wr1dv5pR7.png?imageslim"
                      alt="mark"
                ></p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：<span class="string">&quot;23&quot;</span></span><br><span class="line">输出：[<span class="string">&quot;ad&quot;</span>, <span class="string">&quot;ae&quot;</span>, <span class="string">&quot;af&quot;</span>, <span class="string">&quot;bd&quot;</span>, <span class="string">&quot;be&quot;</span>, <span class="string">&quot;bf&quot;</span>, <span class="string">&quot;cd&quot;</span>, <span class="string">&quot;ce&quot;</span>, <span class="string">&quot;cf&quot;</span>].</span><br></pre></td></tr></table></figure>

<p><strong>说明:</strong><br>尽管上面的答案是按字典序排列的，但是你可以任意选择答案输出的顺序。</p>
<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">String[] letter=&#123;<span class="string">&quot; &quot;</span>,<span class="string">&quot;&quot;</span>,<span class="string">&quot;abc&quot;</span>,<span class="string">&quot;def&quot;</span>,<span class="string">&quot;ghi&quot;</span>,<span class="string">&quot;jkl&quot;</span>,<span class="string">&quot;mno&quot;</span>,<span class="string">&quot;pqrs&quot;</span>,<span class="string">&quot;tuv&quot;</span>,<span class="string">&quot;wxyz&quot;</span>&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> List&lt;String&gt; res=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;String&gt; <span class="title">letterCombinations</span><span class="params">(String digits)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//空字符串要注意</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="string">&quot;&quot;</span>.equals(digits)) <span class="keyword">return</span> res;</span><br><span class="line">    letterCombinations(digits,<span class="number">0</span>,<span class="string">&quot;&quot;</span>);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">letterCombinations</span><span class="params">(String digits,<span class="keyword">int</span> index,String str)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//递归出口,当index==digits的长度的时候就说明走到尽头了</span></span><br><span class="line">    <span class="comment">//需要回头尝试其他的情况</span></span><br><span class="line">    <span class="keyword">if</span> (index==digits.length()) &#123;</span><br><span class="line">        res.add(str);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//当前字符对应的字母组合</span></span><br><span class="line">    <span class="keyword">char</span>[] ls=letter[digits.charAt(index)-<span class="number">48</span>].toCharArray();</span><br><span class="line">    <span class="comment">//遍历每种可能,其实就是DFS</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;ls.length;i++) &#123;</span><br><span class="line">        letterCombinations(digits,index+<span class="number">1</span>,str+ls[i]);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>可想而知，这个算法的时间复杂度相当高，<code>3^N * 4^M = O(2^N)</code> M是能表示3个字符的数字个数，N是表示4个字符的数字个数，指数级别的算法，但是也没有其他别的比较好的算法了</p>
<h2 id="93-复原IP地址"><a href="#93-复原IP地址" class="headerlink" title="93. 复原IP地址"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/restore-ip-addresses/" >93. 复原IP地址<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个只包含数字的字符串，复原它并返回所有可能的 IP 地址格式。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="string">&quot;25525511135&quot;</span></span><br><span class="line">输出: [<span class="string">&quot;255.255.11.135&quot;</span>, <span class="string">&quot;255.255.111.35&quot;</span>]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>其实还是有一个大致的思路，但是没写出来，很多细节不知道咋处理</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;String&gt; <span class="title">restoreIpAddresses</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">    restoreIpAddresses(s,<span class="number">0</span>,<span class="string">&quot;&quot;</span>,<span class="number">0</span>);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">LinkedList&lt;String&gt; res=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">restoreIpAddresses</span><span class="params">(String s,<span class="keyword">int</span> index,String des,<span class="keyword">int</span> count)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (count&gt;<span class="number">4</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//到字符串末尾了</span></span><br><span class="line">    <span class="keyword">if</span> (index==s.length()) &#123;</span><br><span class="line">        <span class="keyword">if</span> (count==<span class="number">4</span>) &#123;</span><br><span class="line">            res.add(des.substring(<span class="number">0</span>,des.length()-<span class="number">1</span>));    </span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//如果为0就不用切分了,这里就相当于直接跳过</span></span><br><span class="line">    <span class="keyword">if</span> (s.charAt(index)==<span class="string">&#x27;0&#x27;</span>) &#123;</span><br><span class="line">        restoreIpAddresses(s,index+<span class="number">1</span>,des+<span class="string">&quot;0.&quot;</span>,count+<span class="number">1</span>);</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        <span class="comment">//不为0就需要继续切分为1，2，3</span></span><br><span class="line">        <span class="comment">//切分过程中需要注意要小于255,同时需要一个计数器来判度是否终止</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;<span class="number">4</span>;i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (index+i&lt;=s.length()) &#123;</span><br><span class="line">                String temp=s.substring(index,index+i);</span><br><span class="line">                <span class="keyword">if</span> (Integer.valueOf(temp)&lt;=<span class="number">255</span>)&#123;</span><br><span class="line">                    restoreIpAddresses(s,index+i,des+temp+<span class="string">&quot;.&quot;</span>,count+<span class="number">1</span>);    </span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>UPDATE: 2020.8.9</strong></p>
<p>今天的打卡题，用go重写了下，比之前写的好多了，不过一开始忘了处理0WA了一发，然后懒的对长度不合法的剪枝又T了一发。。。</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">restoreIpAddresses</span><span class="params">(s <span class="keyword">string</span>)</span> []<span class="title">string</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> res []<span class="keyword">string</span></span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">len</span>(s) &lt; <span class="number">4</span> || <span class="built_in">len</span>(s) &gt; <span class="number">12</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> res</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(s <span class="keyword">string</span>, lis []<span class="keyword">string</span>)</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(s <span class="keyword">string</span>, lis []<span class="keyword">string</span>)</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> s == <span class="string">&quot;&quot;</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> <span class="built_in">len</span>(lis) == <span class="number">4</span> &#123;</span><br><span class="line">                res = <span class="built_in">append</span>(res, strings.Join(lis, <span class="string">&quot;.&quot;</span>))</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//s未遍历完就集齐了4块</span></span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">len</span>(lis) &gt;= <span class="number">4</span> &#123;</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> i := <span class="number">1</span>; i &lt;= <span class="number">3</span>; i++ &#123;</span><br><span class="line">            <span class="keyword">if</span> i &lt;= <span class="built_in">len</span>(s) &amp;&amp; check(s[:i]) &#123;</span><br><span class="line">                lis = <span class="built_in">append</span>(lis, s[:i])</span><br><span class="line">                dfs(s[i:], lis)</span><br><span class="line">                lis = lis[:<span class="built_in">len</span>(lis)<span class="number">-1</span>]</span><br><span class="line">                <span class="comment">//前导0的处理，读取0之后就不再向后扩展</span></span><br><span class="line">                <span class="keyword">if</span> s[:i] == <span class="string">&quot;0&quot;</span> &#123;</span><br><span class="line">                    <span class="keyword">return</span></span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(s, []<span class="keyword">string</span>&#123;&#125;)</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">check</span><span class="params">(s <span class="keyword">string</span>)</span> <span class="title">bool</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> ns, _ := strconv.Atoi(s); ns &lt;= <span class="number">255</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="131-分割回文串"><a href="#131-分割回文串" class="headerlink" title="131. 分割回文串"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/palindrome-partitioning/" >131. 分割回文串<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个字符串 s，将 s 分割成一些子串，使每个子串都是回文串。</p>
<p>返回 s 所有可能的分割方案。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="string">&quot;aab&quot;</span></span><br><span class="line">输出:</span><br><span class="line">[</span><br><span class="line">  [<span class="string">&quot;aa&quot;</span>,<span class="string">&quot;b&quot;</span>],</span><br><span class="line">  [<span class="string">&quot;a&quot;</span>,<span class="string">&quot;a&quot;</span>,<span class="string">&quot;b&quot;</span>]</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>总算自己完整做了一题出来了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> List&lt;List&lt;String&gt;&gt; partition(String s) &#123;</span><br><span class="line">    partition(s,<span class="number">0</span>,<span class="keyword">new</span> ArrayList());</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;   </span><br><span class="line"></span><br><span class="line">List&lt;List&lt;String&gt;&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">partition</span><span class="params">(String s,<span class="keyword">int</span> index,List&lt;String&gt; lis)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (index==s.length()) &#123;</span><br><span class="line">        <span class="comment">//注意这里要copy一个list不能直接添加lis</span></span><br><span class="line">        <span class="comment">//lis引用的对象后面还会继续变化，最后会变为null</span></span><br><span class="line">        res.add(<span class="keyword">new</span> ArrayList(lis));</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=index+<span class="number">1</span>;i&lt;=s.length();i++) &#123;</span><br><span class="line">        String temp=s.substring(index,i);</span><br><span class="line">        <span class="comment">//System.out.println(index+&quot;=&quot;+i+&quot;=&quot;+temp);</span></span><br><span class="line">        <span class="keyword">if</span> (isPalind(temp)) &#123;</span><br><span class="line">            lis.add(temp);</span><br><span class="line">            partition(s,i,lis);</span><br><span class="line">            <span class="comment">//不能直接remove(temp),主要是会有重复的字符,所以会导致最后的顺序不一致,而且效率也很低</span></span><br><span class="line">            <span class="comment">//lis.remove(temp);</span></span><br><span class="line">            lis.remove(lis.size()-<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isPalind</span><span class="params">(String s)</span></span>&#123;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>,j=s.length()-<span class="number">1</span>;i&lt;=j;i++,j--) &#123;</span><br><span class="line">        <span class="keyword">if</span> (s.charAt(i)!=s.charAt(j)) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>4ms，93%，其实就是暴力回溯，还是挺简单的，一开始忘了<code>remove()</code>，直接把所有结果打出来了， 然后一直在想怎么调整递归的结构。。。DFS基本的套路都忘了😂</p>
<h2 id="46-全排列"><a href="#46-全排列" class="headerlink" title="46. 全排列"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/permutations/" >46. 全排列<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个<strong>没有重复</strong>数字的序列，返回其所有可能的全排列。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line">输出:</span><br><span class="line">[</span><br><span class="line">  [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],</span><br><span class="line">  [<span class="number">1</span>,<span class="number">3</span>,<span class="number">2</span>],</span><br><span class="line">  [<span class="number">2</span>,<span class="number">1</span>,<span class="number">3</span>],</span><br><span class="line">  [<span class="number">2</span>,<span class="number">3</span>,<span class="number">1</span>],</span><br><span class="line">  [<span class="number">3</span>,<span class="number">1</span>,<span class="number">2</span>],</span><br><span class="line">  [<span class="number">3</span>,<span class="number">2</span>,<span class="number">1</span>]</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>经典的全排列问题，熟悉了DFS套路之后都挺简单的，注意回溯就行了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; permute(<span class="keyword">int</span>[] nums) &#123;</span><br><span class="line">    <span class="keyword">if</span> (nums==<span class="keyword">null</span> || nums.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">boolean</span>[] visit=<span class="keyword">new</span> <span class="keyword">boolean</span>[nums.length];</span><br><span class="line">    permute(nums,<span class="keyword">new</span> ArrayList(),visit);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> List&lt;List&lt;Integer&gt;&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">permute</span><span class="params">(<span class="keyword">int</span>[] nums,List&lt;Integer&gt; lis,<span class="keyword">boolean</span>[] visit)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (lis.size()==nums.length) &#123;</span><br><span class="line">        res.add(<span class="keyword">new</span> ArrayList(lis));</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.length;i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (visit[i]) <span class="keyword">continue</span>;</span><br><span class="line">        lis.add(nums[i]);</span><br><span class="line">        visit[i]=<span class="keyword">true</span>;</span><br><span class="line">        permute(nums,lis,visit);</span><br><span class="line">        <span class="comment">//回溯</span></span><br><span class="line">        visit[i]=<span class="keyword">false</span>;</span><br><span class="line">        lis.remove(lis.size()-<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="60-第k个排列"><a href="#60-第k个排列" class="headerlink" title="60. 第k个排列"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/permutation-sequence/" >60. 第k个排列<i class="fas fa-external-link-alt"></i></a></h2><p>给出集合 [1,2,3,…,n]，其所有元素共有 n! 种排列。</p>
<p>按大小顺序列出所有排列情况，并一一标记，当 n = 3 时, 所有排列如下：</p>
<ol>
<li><code>&quot;123&quot;</code></li>
<li><code>&quot;132&quot;</code></li>
<li><code>&quot;213&quot;</code></li>
<li><code>&quot;231&quot;</code></li>
<li><code>&quot;312&quot;</code></li>
<li><code>&quot;321&quot;</code></li>
</ol>
<p>给定 n 和 k，返回第 k 个排列。</p>
<p><strong>说明：</strong></p>
<ul>
<li>给定 n 的范围是 [1, 9]。</li>
<li>给定 k 的范围是[1,  n!]。</li>
</ul>
<p>**示例 1: **</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: n = <span class="number">3</span>, k = <span class="number">3</span></span><br><span class="line">输出: <span class="string">&quot;213&quot;</span></span><br></pre></td></tr></table></figure>


<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: n = <span class="number">4</span>, k = <span class="number">9</span></span><br><span class="line">输出: <span class="string">&quot;2314&quot;</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">getPermutation</span><span class="params">(<span class="keyword">int</span> n, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">boolean</span>[] visit=<span class="keyword">new</span> <span class="keyword">boolean</span>[n+<span class="number">1</span>];</span><br><span class="line">    getPermutation(n,k,<span class="number">0</span>,visit,<span class="keyword">new</span> StringBuilder(<span class="string">&quot;&quot;</span>));</span><br><span class="line">    <span class="keyword">return</span> res.get(k-<span class="number">1</span>).toString();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> List&lt;StringBuilder&gt; res=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">getPermutation</span><span class="params">(<span class="keyword">int</span> n, <span class="keyword">int</span> k,<span class="keyword">int</span> count,<span class="keyword">boolean</span>[] visit,StringBuilder str)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (count == n) &#123;</span><br><span class="line">        res.add(<span class="keyword">new</span> StringBuilder(str));</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (res.size()==k) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;=n;i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!visit[i]) &#123;</span><br><span class="line">            str.append(i);</span><br><span class="line">            visit[i]=<span class="keyword">true</span>;</span><br><span class="line">            getPermutation(n,k,count+<span class="number">1</span>,visit,str);</span><br><span class="line">            visit[i]=<span class="keyword">false</span>;</span><br><span class="line">            str.delete(str.length()-<span class="number">1</span>,str.length());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>偶然发现这一题并没有记录，之前没有记录的原因肯定是因为方法太垃圾了，这题最优解是 <code>康托展开</code>，说实话，暂时并不想去了解😂，后面有时间再说吧</p>
<h2 id="5374-长度为-n-的开心字符串中字典序第-k-小的字符串"><a href="#5374-长度为-n-的开心字符串中字典序第-k-小的字符串" class="headerlink" title="5374. 长度为 n 的开心字符串中字典序第 k 小的字符串"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/the-k-th-lexicographical-string-of-all-happy-strings-of-length-n/" >5374. 长度为 n 的开心字符串中字典序第 k 小的字符串<i class="fas fa-external-link-alt"></i></a></h2><p>一个 「开心字符串」定义为：</p>
<ul>
<li>仅包含小写字母 [‘a’, ‘b’, ‘c’].</li>
<li>对所有在 1 到 s.length - 1 之间的 i ，满足 s[i] != s[i + 1] （字符串的下标从 1 开始）。</li>
</ul>
<p>比方说，字符串 “abc”，”ac”，”b” 和 “abcbabcbcb” 都是开心字符串，但是 “aa”，”baa” 和 “ababbc” 都不是开心字符串。</p>
<p>给你两个整数 n 和 k ，你需要将长度为 n 的所有开心字符串按字典序排序。</p>
<p>请你返回排序后的第 k 个开心字符串，如果长度为 n 的开心字符串少于 k 个，那么请你返回 空字符串 。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：n = <span class="number">1</span>, k = <span class="number">3</span></span><br><span class="line">输出：<span class="string">&quot;c&quot;</span></span><br><span class="line">解释：列表 [<span class="string">&quot;a&quot;</span>, <span class="string">&quot;b&quot;</span>, <span class="string">&quot;c&quot;</span>] 包含了所有长度为 <span class="number">1</span> 的开心字符串。按照字典序排序后第三个字符串为 <span class="string">&quot;c&quot;</span> 。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：n = <span class="number">1</span>, k = <span class="number">4</span></span><br><span class="line">输出：<span class="string">&quot;&quot;</span></span><br><span class="line">解释：长度为 <span class="number">1</span> 的开心字符串只有 <span class="number">3</span> 个。</span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：n = <span class="number">3</span>, k = <span class="number">9</span></span><br><span class="line">输出：<span class="string">&quot;cab&quot;</span></span><br><span class="line">解释：长度为 <span class="number">3</span> 的开心字符串总共有 <span class="number">12</span> 个 [<span class="string">&quot;aba&quot;</span>, <span class="string">&quot;abc&quot;</span>, <span class="string">&quot;aca&quot;</span>, <span class="string">&quot;acb&quot;</span>, <span class="string">&quot;bab&quot;</span>, <span class="string">&quot;bac&quot;</span>, <span class="string">&quot;bca&quot;</span>, <span class="string">&quot;bcb&quot;</span>, <span class="string">&quot;cab&quot;</span>, <span class="string">&quot;cac&quot;</span>, <span class="string">&quot;cba&quot;</span>, <span class="string">&quot;cbc&quot;</span>] 。第 <span class="number">9</span> 个字符串为 <span class="string">&quot;cab&quot;</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 4：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：n = <span class="number">2</span>, k = <span class="number">7</span></span><br><span class="line">输出：<span class="string">&quot;&quot;</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 5：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：n = <span class="number">10</span>, k = <span class="number">100</span></span><br><span class="line">输出：<span class="string">&quot;abacbabacb&quot;</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li><code>1 &lt;= n &lt;= 10</code></li>
<li><code>1 &lt;= k &lt;= 100</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>补下24th双周赛T3，和上面一题很类似，直接暴力回溯了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">getHappyString</span><span class="params">(<span class="keyword">int</span> n, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    dfs(<span class="string">&quot;a&quot;</span>,n,k);</span><br><span class="line">    dfs(<span class="string">&quot;b&quot;</span>,n,k);</span><br><span class="line">    dfs(<span class="string">&quot;c&quot;</span>,n,k);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> count=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> String res=<span class="string">&quot;&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(String cur,<span class="keyword">int</span> n,<span class="keyword">int</span> k)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(!<span class="string">&quot;&quot;</span>.equals(res)) <span class="keyword">return</span>;</span><br><span class="line">    <span class="keyword">if</span>(cur.length()==n)&#123;</span><br><span class="line">        count++;</span><br><span class="line">        <span class="keyword">if</span>(count==k)&#123;</span><br><span class="line">            res=cur;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">char</span> last=cur.charAt(cur.length()-<span class="number">1</span>);</span><br><span class="line">    <span class="keyword">if</span>(last==<span class="string">&#x27;a&#x27;</span>)&#123;</span><br><span class="line">        dfs(cur+<span class="string">&#x27;b&#x27;</span>,n,k);</span><br><span class="line">        dfs(cur+<span class="string">&#x27;c&#x27;</span>,n,k);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(last==<span class="string">&#x27;b&#x27;</span>)&#123;</span><br><span class="line">        dfs(cur+<span class="string">&#x27;a&#x27;</span>,n,k);</span><br><span class="line">        dfs(cur+<span class="string">&#x27;c&#x27;</span>,n,k);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(last==<span class="string">&#x27;c&#x27;</span>)&#123;</span><br><span class="line">        dfs(cur+<span class="string">&#x27;a&#x27;</span>,n,k);</span><br><span class="line">        dfs(cur+<span class="string">&#x27;b&#x27;</span>,n,k);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>其实直接队列模拟也是可以的，模拟的效率应该会更高一些，好像也可以直接构造出来</p>
<h2 id="47-全排列-II"><a href="#47-全排列-II" class="headerlink" title="47. 全排列 II"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/permutations-ii/" >47. 全排列 II<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个可包含重复数字的序列，返回所有不重复的全排列。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">1</span>,<span class="number">2</span>]</span><br><span class="line">输出:</span><br><span class="line">[</span><br><span class="line">  [<span class="number">1</span>,<span class="number">1</span>,<span class="number">2</span>],</span><br><span class="line">  [<span class="number">1</span>,<span class="number">2</span>,<span class="number">1</span>],</span><br><span class="line">  [<span class="number">2</span>,<span class="number">1</span>,<span class="number">1</span>]</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>开始我很纠结这题，后来想通了，其实就是去重，遇到已经存在于结果中相同的元素就直接跳过就行了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; permuteUnique(<span class="keyword">int</span>[] nums) &#123;</span><br><span class="line">    <span class="keyword">if</span> (nums==<span class="keyword">null</span> || nums.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//Arrays.sort(nums); 解法二需要先排序</span></span><br><span class="line">    <span class="keyword">boolean</span>[] visit=<span class="keyword">new</span> <span class="keyword">boolean</span>[nums.length];</span><br><span class="line">    permuteUnique(nums,<span class="keyword">new</span> ArrayList(),visit);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> List&lt;List&lt;Integer&gt;&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">permuteUnique</span><span class="params">(<span class="keyword">int</span>[] nums,List&lt;Integer&gt; lis,<span class="keyword">boolean</span>[] visit)</span></span>&#123;</span><br><span class="line">    HashSet&lt;Integer&gt; set=<span class="keyword">new</span> HashSet&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (lis.size()==nums.length) &#123;</span><br><span class="line">        res.add(<span class="keyword">new</span> ArrayList(lis));</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.length;i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!visit[i] &amp;&amp; !set.contains(nums[i])) &#123;</span><br><span class="line">            lis.add(nums[i]);</span><br><span class="line">            visit[i]=<span class="keyword">true</span>;</span><br><span class="line">            set.add(nums[i]);</span><br><span class="line">            permuteUnique(nums,lis,visit);</span><br><span class="line">            visit[i]=<span class="keyword">false</span>;</span><br><span class="line">            lis.remove(lis.size()-<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//需要排序</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">permuteUnique2</span><span class="params">(<span class="keyword">int</span>[] nums,List&lt;Integer&gt; lis,<span class="keyword">boolean</span>[] visit)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (lis.size()==nums.length) &#123;</span><br><span class="line">        res.add(<span class="keyword">new</span> ArrayList(lis));</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.length;i++) &#123;</span><br><span class="line">        <span class="comment">//剪枝去重，和前一个元素比较</span></span><br><span class="line">        <span class="comment">//Bug警告，应该写!visit[i-1]</span></span><br><span class="line">        <span class="keyword">if</span> (i&gt;<span class="number">0</span>&amp;&amp;nums[i]==nums[i-<span class="number">1</span>] &amp;&amp; !visit[i-<span class="number">1</span>]) </span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        <span class="keyword">if</span> (!visit[i]) &#123;</span><br><span class="line">            lis.add(nums[i]);</span><br><span class="line">            visit[i]=<span class="keyword">true</span>;</span><br><span class="line">            permuteUnique2(nums,lis,visit);</span><br><span class="line">            visit[i]=<span class="keyword">false</span>;</span><br><span class="line">            lis.remove(lis.size()-<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>关于去重的方式，其实我们可以从回溯的<strong>根节点</strong>来考虑，也就是我们考虑最顶层的【<strong>1，1，2</strong>】的遍历情况，每一次遍历实际上都是在找<strong>以当前元素开头的排列</strong>，当第一次已经遍历完1开头的所以排列后，后面的循环再碰到1自然就可以直接跳过了，所以我们可以在一次遍历中用HashMap来去重，来保证一次循环中不会有重复的元素被选取，其实也只有这题可以用HashSet，因为这里排列是讲究顺序的，循序完全一样才是重复，后面的题都是不讲究顺序的，都需要排序才能去重，具体后面再分析</p>
<blockquote>
<p>我首先想到的就是Hash表，这里翻了下评论区好像都是用的第二种方式去重的，难道用HashSet不好么😂，第二种必须要先排序，保证相同的元素都聚在一起，方便判断，这种题在纸上画一画递归树其实就很清楚了</p>
</blockquote>
<h3 id="Bug警告"><a href="#Bug警告" class="headerlink" title="Bug警告"></a>Bug警告</h3><p>这里 <code>!visit[i-1]</code>和 <code>visit[i-1]</code>对于这题来说并不影响正确性，但是你如果将生成的过程打印出来对比下就知道为啥了，具体的请看下面 <a href="#1079-%E6%B4%BB%E5%AD%97%E5%8D%B0%E5%88%B7">1079. 活字印刷</a> 的解释</p>
<h2 id="1286-字母组合迭代器"><a href="#1286-字母组合迭代器" class="headerlink" title="1286. 字母组合迭代器"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/iterator-for-combination/" >1286. 字母组合迭代器<i class="fas fa-external-link-alt"></i></a></h2><p>请你设计一个迭代器类，包括以下内容：</p>
<ul>
<li>一个构造函数，输入参数包括：一个 有序且字符唯一 的字符串 characters（该字符串只包含小写英文字母）和一个数字 combinationLength 。</li>
<li>函数 next() ，按 字典序 返回长度为 combinationLength 的下一个字母组合。</li>
<li>函数 hasNext() ，只有存在长度为 combinationLength 的下一个字母组合时，才返回 True；否则，返回 False。</li>
</ul>
<p><strong>示例：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">CombinationIterator iterator = <span class="keyword">new</span> CombinationIterator(<span class="string">&quot;abc&quot;</span>, <span class="number">2</span>); <span class="comment">// 创建迭代器 iterator</span></span><br><span class="line"></span><br><span class="line">iterator.next(); <span class="comment">// 返回 &quot;ab&quot;</span></span><br><span class="line">iterator.hasNext(); <span class="comment">// 返回 true</span></span><br><span class="line">iterator.next(); <span class="comment">// 返回 &quot;ac&quot;</span></span><br><span class="line">iterator.hasNext(); <span class="comment">// 返回 true</span></span><br><span class="line">iterator.next(); <span class="comment">// 返回 &quot;bc&quot;</span></span><br><span class="line">iterator.hasNext(); <span class="comment">// 返回 false</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>1 &lt;= combinationLength &lt;= characters.length &lt;= 15</li>
<li>每组测试数据最多包含 10^4 次函数调用。</li>
<li>题目保证每次调用函数 next 时都存在下一个字母组合。</li>
</ul>
<p><strong>解法一</strong></p>
<p>唉，真的菜，好久没写回溯了，又給忘了，这题开始被别人误导了，以为是下一个排列，然后就一直在想怎么去求next，其实根本就不用这样…</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> LinkedList&lt;String&gt; res=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="comment">//abc</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">CombinationIterator</span><span class="params">(String characters, <span class="keyword">int</span> combinationLength)</span> </span>&#123;</span><br><span class="line">    dfs(<span class="string">&quot;&quot;</span>,combinationLength,<span class="number">0</span>,<span class="number">0</span>,characters);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">next</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> res.pollFirst();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(String cur,<span class="keyword">int</span> len,<span class="keyword">int</span> index,<span class="keyword">int</span> count,String source)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (count == len) &#123;</span><br><span class="line">        res.add(cur); <span class="comment">//直接根据cur得长度判断就ok了</span></span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=index;i&lt;source.length();i++) &#123;</span><br><span class="line">        dfs(cur+source.charAt(i),len,i+<span class="number">1</span>,count+<span class="number">1</span>,source);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">hasNext</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> !res.isEmpty();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>回头开了下之前的代码，发现都写得不好，很喜欢加个count统计数量，其实直接根据cur得长度判断就可以了</p>
</blockquote>
<h2 id="77-组合"><a href="#77-组合" class="headerlink" title="77. 组合"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/combinations/" >77. 组合<i class="fas fa-external-link-alt"></i></a></h2><p>给定两个整数 n 和 k，返回 1 … n 中所有可能的 k 个数的组合。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: n = <span class="number">4</span>, k = <span class="number">2</span></span><br><span class="line">输出:</span><br><span class="line">[</span><br><span class="line">  [<span class="number">2</span>,<span class="number">4</span>],</span><br><span class="line">  [<span class="number">3</span>,<span class="number">4</span>],</span><br><span class="line">  [<span class="number">2</span>,<span class="number">3</span>],</span><br><span class="line">  [<span class="number">1</span>,<span class="number">2</span>],</span><br><span class="line">  [<span class="number">1</span>,<span class="number">3</span>],</span><br><span class="line">  [<span class="number">1</span>,<span class="number">4</span>],</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>其实一开始没写出剪枝的代码，看了一点提示后才写出了下面的的第一种剪枝的方法</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; combine(<span class="keyword">int</span> n, <span class="keyword">int</span> k) &#123;</span><br><span class="line">    <span class="keyword">if</span> (k&gt;n || n&lt;=<span class="number">0</span> ||k&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//boolean[] visit=new boolean[n+1];</span></span><br><span class="line">    combine(n,k,<span class="number">1</span>,<span class="keyword">new</span> ArrayList(),<span class="number">0</span>);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;   </span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> List&lt;List&lt;Integer&gt;&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="comment">//剪枝优化1</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">combine</span><span class="params">(<span class="keyword">int</span> n, <span class="keyword">int</span> k,<span class="keyword">int</span> index,List&lt;Integer&gt; lis,<span class="keyword">int</span> count)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (count==k) &#123;</span><br><span class="line">        res.add(<span class="keyword">new</span> ArrayList(lis));</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//1 2 3 4 | 3</span></span><br><span class="line">    <span class="comment">//index = 3 k=3  n=4 count=0 (3为头,显然是不行的,肯定会和前面重复) --&gt; 3&lt;=3</span></span><br><span class="line">    <span class="comment">//index = 3 k=3  n=4 count=1 (3为第二个,是可行的) --&gt; 3 &lt;= 2</span></span><br><span class="line">    <span class="keyword">if</span> (n-index+<span class="number">2</span>&lt;=k-count) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=index;i&lt;=n;i++) &#123;</span><br><span class="line">        lis.add(i);</span><br><span class="line">        combine(n,k,i+<span class="number">1</span>,lis,count+<span class="number">1</span>);</span><br><span class="line">        <span class="comment">//回溯的关键</span></span><br><span class="line">        lis.remove(lis.size()-<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//剪枝优化2</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">combine4</span><span class="params">(<span class="keyword">int</span> n, <span class="keyword">int</span> k,<span class="keyword">int</span> index,List&lt;Integer&gt; lis,<span class="keyword">int</span> count)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (count==k) &#123;</span><br><span class="line">        res.add(<span class="keyword">new</span> ArrayList(lis));</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//循环的区间至少要有k-count个元素 也就是[i,N]之间至少要有k-count个元素</span></span><br><span class="line">    <span class="comment">//N-i+1&gt;=k-count --&gt; i&lt;=n-(k-count)+1</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=index;i&lt;=n-(k-count)+<span class="number">1</span>;i++) &#123;</span><br><span class="line">        lis.add(i);</span><br><span class="line">        combine4(n,k,i+<span class="number">1</span>,lis,count+<span class="number">1</span>);</span><br><span class="line">        <span class="comment">//回溯的关键</span></span><br><span class="line">        lis.remove(lis.size()-<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>举个例子<code>1，2，3，4 k=3</code>  其实在循环n=3的时候就可以结束了，因为后面已经没有那么多元素可以和3构成组合了</p>
<h2 id="39-组合总和"><a href="#39-组合总和" class="headerlink" title="39. 组合总和"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/combination-sum/" >39. 组合总和<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个无重复元素的数组 candidates 和一个目标数 target ，找出 candidates 中所有可以使数字和为 target 的组合 ，<code>candidates</code> 中的数字可以无限制重复被选取</p>
<p>说明：</p>
<ul>
<li><p>所有数字（包括 target）都是正整数。</p>
</li>
<li><p>解集不能包含重复的组合。 </p>
</li>
</ul>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: candidates = [<span class="number">2</span>,<span class="number">3</span>,<span class="number">6</span>,<span class="number">7</span>], target = <span class="number">7</span>,</span><br><span class="line">所求解集为:</span><br><span class="line">[</span><br><span class="line">  [<span class="number">7</span>],</span><br><span class="line">  [<span class="number">2</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line">]</span><br></pre></td></tr></table></figure>


<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: candidates = [<span class="number">2</span>,<span class="number">3</span>,<span class="number">5</span>], target = <span class="number">8</span>,</span><br><span class="line">所求解集为:</span><br><span class="line">[</span><br><span class="line">  [<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>],</span><br><span class="line">  [<span class="number">2</span>,<span class="number">3</span>,<span class="number">3</span>],</span><br><span class="line">  [<span class="number">3</span>,<span class="number">5</span>]</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>没有任何剪枝处理的回溯，感觉一开始就想好怎么剪枝还是不太容易，这题其实和上面的组合很类似，值得注意的就是子递归调用的时候传递的index参数</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; combinationSum(<span class="keyword">int</span>[] candidates, <span class="keyword">int</span> target) &#123;</span><br><span class="line">    <span class="keyword">if</span> (candidates==<span class="keyword">null</span> || candidates.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    combinationSum(candidates,target,<span class="number">0</span>,<span class="number">0</span>,<span class="keyword">new</span> ArrayList());</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> List&lt;List&lt;Integer&gt;&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">combinationSum</span><span class="params">(<span class="keyword">int</span>[] candidates, <span class="keyword">int</span> target,<span class="keyword">int</span> index,<span class="keyword">int</span> sum,List&lt;Integer&gt; lis)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (sum&gt;target) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (target==sum) &#123;</span><br><span class="line">        res.add(<span class="keyword">new</span> ArrayList(lis));</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//这里一次循环其实就确定了包含i的所有可能解，所以起点是index不是0</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=index;i&lt;candidates.length;i++) &#123;</span><br><span class="line">        <span class="comment">//跳过比target大的</span></span><br><span class="line">        <span class="keyword">if</span> (candidates[i]&gt;target) <span class="keyword">continue</span>;</span><br><span class="line">        sum+=candidates[i];</span><br><span class="line">        lis.add(candidates[i]);</span><br><span class="line">		<span class="comment">//其实主要就是搞清楚每次从哪里开始,以及每次循环的作用</span></span><br><span class="line">        <span class="comment">//可以重复选取自己，所以子递归也从i开始而不是i+1</span></span><br><span class="line">        combinationSum(candidates,target,i,sum,lis);</span><br><span class="line">        sum-=candidates[i];</span><br><span class="line">        lis.remove(lis.size()-<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>剪枝优化，主要是要先排个序，这样如果在循环过程中，累加和已经大于target了就直接return，如果不排序就不能return，因为无法确保后面会不会更小的元素</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; combinationSum(<span class="keyword">int</span>[] candidates, <span class="keyword">int</span> target) &#123;</span><br><span class="line">    <span class="keyword">if</span> (candidates==<span class="keyword">null</span> || candidates.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//排序,方便剪枝</span></span><br><span class="line">    Arrays.sort(candidates);</span><br><span class="line">    combinationSum(candidates,target,<span class="number">0</span>,<span class="number">0</span>,<span class="keyword">new</span> ArrayList());</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> List&lt;List&lt;Integer&gt;&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="comment">//剪枝优化2</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">combinationSum</span><span class="params">(<span class="keyword">int</span>[] candidates, <span class="keyword">int</span> target,<span class="keyword">int</span> index,<span class="keyword">int</span> sum,List&lt;Integer&gt; lis)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (sum&gt;target) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (target==sum) &#123;</span><br><span class="line">        res.add(<span class="keyword">new</span> ArrayList(lis));</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=index;i&lt;candidates.length;i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (sum+candidates[i]&gt;target) <span class="keyword">return</span>;</span><br><span class="line">        sum+=candidates[i];</span><br><span class="line">        lis.add(candidates[i]);</span><br><span class="line">        <span class="comment">//注意这里传递进去的index是i</span></span><br><span class="line">        combinationSum(candidates,target,i,sum,lis);</span><br><span class="line">        sum-=candidates[i];</span><br><span class="line">        lis.remove(lis.size()-<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这两天状态还可以啊，好多题都可以完全独立的写出来了😁</p>
<h2 id="40-组合总和-II"><a href="#40-组合总和-II" class="headerlink" title="40. 组合总和 II"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/combination-sum-ii/" >40. 组合总和 II<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个数组 candidates 和一个目标数 target ，找出 candidates 中所有可以使数字和为 target 的组合。</p>
<p>candidates 中的每个数字在每个组合中只能使用一次。</p>
<p><strong>说明：</strong></p>
<ul>
<li>所有数字（包括目标数）都是正整数。</li>
<li>解集不能包含重复的组合。 </li>
</ul>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: candidates = [<span class="number">10</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">7</span>,<span class="number">6</span>,<span class="number">1</span>,<span class="number">5</span>], target = <span class="number">8</span>,</span><br><span class="line">所求解集为:</span><br><span class="line">[</span><br><span class="line">  [<span class="number">1</span>, <span class="number">7</span>],</span><br><span class="line">  [<span class="number">1</span>, <span class="number">2</span>, <span class="number">5</span>],</span><br><span class="line">  [<span class="number">2</span>, <span class="number">6</span>],</span><br><span class="line">  [<span class="number">1</span>, <span class="number">1</span>, <span class="number">6</span>]</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: candidates = [<span class="number">2</span>,<span class="number">5</span>,<span class="number">2</span>,<span class="number">1</span>,<span class="number">2</span>], target = <span class="number">5</span>,</span><br><span class="line">所求解集为:</span><br><span class="line">[</span><br><span class="line">  [<span class="number">1</span>,<span class="number">2</span>,<span class="number">2</span>],</span><br><span class="line">  [<span class="number">5</span>]</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; combinationSum2(<span class="keyword">int</span>[] candidates, <span class="keyword">int</span> target) &#123;</span><br><span class="line">    <span class="keyword">if</span> (candidates ==<span class="keyword">null</span> || candidates.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    Arrays.sort(candidates);</span><br><span class="line">    combinationSum2(candidates,target,<span class="number">0</span>,<span class="keyword">new</span> ArrayList());</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">combinationSum2</span><span class="params">(<span class="keyword">int</span>[] candidates, <span class="keyword">int</span> target,<span class="keyword">int</span> index,List&lt;Integer&gt; lis)</span> </span>&#123;</span><br><span class="line">    <span class="comment">/*if (target&lt;0) &#123;</span></span><br><span class="line"><span class="comment">            return;</span></span><br><span class="line"><span class="comment">        &#125;*/</span></span><br><span class="line">    <span class="keyword">if</span> (target==<span class="number">0</span>) &#123;</span><br><span class="line">        res.add(<span class="keyword">new</span> ArrayList(lis));</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=index;i&lt;candidates.length;i++) &#123;</span><br><span class="line">        <span class="comment">//注意这里i&gt;index</span></span><br><span class="line">        <span class="keyword">if</span> (i&gt;index &amp;&amp; candidates[i]==candidates[i-<span class="number">1</span>]  ) <span class="keyword">continue</span>;</span><br><span class="line">        <span class="comment">//排过序的,可以直接return</span></span><br><span class="line">        <span class="keyword">if</span> (target-candidates[i]&lt;<span class="number">0</span>) <span class="keyword">return</span>;</span><br><span class="line">        lis.add(candidates[i]);</span><br><span class="line">        combinationSum2(candidates,target-candidates[i],i+<span class="number">1</span>,lis);</span><br><span class="line">        lis.remove(lis.size()-<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>回溯其实值得注意的就那几个点，循环的起点，下次递归的起点，回溯，出口，这几个点都搞清楚了其实就很简单了，关键的地方就是如何去重</p>
<p>这题如果参照上面[全排列2](## 47. 全排列 II) 的第一种HashSet的去重方式的话，明显是有问题的，HashSet的去重方式只能保证<strong>每一次循环中不会有重复的元素被选取</strong>，但是这题即使循环中没有重复的元素被选取，结果仍然会有重复</p>
<p>比如 <code>10,1,2,7,6,1,5</code> 遍历1的时候会得到<code>1 2 5</code>，后续遍历2的时候又会得到一个 <code>2 1 5</code> ，但是其实在第一次循环的时候就<strong>已经找到了所有包含1的解，后面循环中包含1的解其实都重复了</strong>，如果我们排序后就变为 <code>1 1 2 5 6 7 10</code> 把相同的元素聚集到一起，一方面可以去重，另一方面还可以剪枝，在第一次循环的时候就已经找到了所有的 带有1的解，后面的连着的1都可以跳过了，后续就不会再有包含1的解了，如果不排序，后面仍然会有包含1的解</p>
<h2 id="216-组合总和-III"><a href="#216-组合总和-III" class="headerlink" title="216. 组合总和 III"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/combination-sum-iii/" >216. 组合总和 III<i class="fas fa-external-link-alt"></i></a></h2><p>找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数，并且每种组合中不存在重复的数字。</p>
<p><strong>说明：</strong></p>
<ul>
<li>所有数字都是正整数。</li>
<li>解集不能包含重复的组合。 </li>
</ul>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: k = <span class="number">3</span>, n = <span class="number">7</span></span><br><span class="line">输出: [[<span class="number">1</span>,<span class="number">2</span>,<span class="number">4</span>]]</span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: k = <span class="number">3</span>, n = <span class="number">9</span></span><br><span class="line">输出: [[<span class="number">1</span>,<span class="number">2</span>,<span class="number">6</span>], [<span class="number">1</span>,<span class="number">3</span>,<span class="number">5</span>], [<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>]]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>感觉比上面两题还简单一点，可以直接剪枝</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="comment">//UPDATE: 2020.9.11</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">combinationSum3</span><span class="params">(k <span class="keyword">int</span>, n <span class="keyword">int</span>)</span> [][]<span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> res [][]<span class="keyword">int</span></span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(idx <span class="keyword">int</span>, sum <span class="keyword">int</span>, lis []<span class="keyword">int</span>)</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(idx <span class="keyword">int</span>, sum <span class="keyword">int</span>, lis []<span class="keyword">int</span>)</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">len</span>(lis) &gt; k &#123;</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> sum == n &amp;&amp; <span class="built_in">len</span>(lis) == k &#123;</span><br><span class="line">            dest := <span class="built_in">make</span>([]<span class="keyword">int</span>, <span class="built_in">len</span>(lis))</span><br><span class="line">            <span class="built_in">copy</span>(dest, lis)</span><br><span class="line">            res = <span class="built_in">append</span>(res, dest)</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> i := idx; i &lt;= <span class="number">9</span>; i++ &#123;</span><br><span class="line">            <span class="keyword">if</span> sum + i &gt; n &#123;</span><br><span class="line">                <span class="keyword">return</span></span><br><span class="line">            &#125;</span><br><span class="line">            dfs(i+<span class="number">1</span>, sum+i, <span class="built_in">append</span>(lis, i))</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(<span class="number">1</span>, <span class="number">0</span>, []<span class="keyword">int</span>&#123;&#125;)</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二（UPDATE：2020.9.11）</strong></p>
<p>学了下二进制枚举子集的方法，很简洁</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">combinationSum3</span><span class="params">(k <span class="keyword">int</span>, n <span class="keyword">int</span>)</span> [][]<span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> res [][]<span class="keyword">int</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; (<span class="number">1</span>&lt;&lt;<span class="number">9</span>); i++ &#123;</span><br><span class="line">        <span class="keyword">var</span> sum, cnt = <span class="number">0</span>, <span class="number">0</span></span><br><span class="line">        <span class="keyword">var</span> lis []<span class="keyword">int</span></span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt; <span class="number">9</span>; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> i &amp; (<span class="number">1</span>&lt;&lt;j) != <span class="number">0</span> &#123;</span><br><span class="line">                sum += j+<span class="number">1</span></span><br><span class="line">                cnt++</span><br><span class="line">                lis = <span class="built_in">append</span>(lis, j+<span class="number">1</span>)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> sum == n &amp;&amp; cnt == k &#123;</span><br><span class="line">            res = <span class="built_in">append</span>(res, lis)   </span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="78-子集"><a href="#78-子集" class="headerlink" title="78. 子集"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/subsets/" >78. 子集<i class="fas fa-external-link-alt"></i></a></h2><p>给定一组<strong>不含重复元素</strong>的整数数组 nums，返回该数组所有可能的子集（幂集）。</p>
<p><strong>说明：</strong>解集不能包含重复的子集。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: nums = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line">输出:</span><br><span class="line">[</span><br><span class="line">  [<span class="number">3</span>],</span><br><span class="line">  [<span class="number">1</span>],</span><br><span class="line">  [<span class="number">2</span>],</span><br><span class="line">  [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],</span><br><span class="line">  [<span class="number">1</span>,<span class="number">3</span>],</span><br><span class="line">  [<span class="number">2</span>,<span class="number">3</span>],</span><br><span class="line">  [<span class="number">1</span>,<span class="number">2</span>],</span><br><span class="line">  []</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> List&lt;List&lt;Integer&gt;&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; subsets(<span class="keyword">int</span>[] nums) &#123;</span><br><span class="line">    <span class="keyword">if</span> (nums==<span class="keyword">null</span> || nums.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    subsets(nums,<span class="number">0</span>,<span class="keyword">new</span> ArrayList());</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">subsets</span><span class="params">(<span class="keyword">int</span>[] nums,<span class="keyword">int</span> index,List&lt;Integer&gt; lis)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//if (index&lt;=nums.length) &#123;</span></span><br><span class="line">        res.add(<span class="keyword">new</span> ArrayList(lis));</span><br><span class="line">    <span class="comment">//&#125;</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=index; i&lt;nums.length;i++) &#123;</span><br><span class="line">        lis.add(nums[i]);</span><br><span class="line">        subsets(nums,i+<span class="number">1</span>,lis);</span><br><span class="line">        lis.remove(lis.size()-<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>简单的回溯，注意收集结果的时机就行</p>
<p><strong>Update: 2020.6.20</strong></p>
<p>增加一个go的写法</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">subsets</span><span class="params">(nums []<span class="keyword">int</span>)</span> [][]<span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> res [][]<span class="keyword">int</span></span><br><span class="line">    <span class="keyword">var</span> lis []<span class="keyword">int</span></span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(index <span class="keyword">int</span>)</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(index <span class="keyword">int</span>)</span></span>&#123;</span><br><span class="line">        dest:=<span class="built_in">make</span>([]<span class="keyword">int</span>,<span class="built_in">len</span>(lis))</span><br><span class="line">        <span class="built_in">copy</span>(dest,lis)</span><br><span class="line">        res=<span class="built_in">append</span>(res,dest)</span><br><span class="line">        <span class="keyword">for</span> i:=index;i&lt;<span class="built_in">len</span>(nums);i++&#123;</span><br><span class="line">            lis=<span class="built_in">append</span>(lis,nums[i])</span><br><span class="line">            dfs(i+<span class="number">1</span>)</span><br><span class="line">            lis=lis[:<span class="built_in">len</span>(lis)<span class="number">-1</span>]</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(<span class="number">0</span>)</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>BFS，类似于二叉树层次遍历，首先初始化一个空的list，后面每次迭代都将list中的所有元素都取出来加上当前元素，再重新加入到list中</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; subsets(<span class="keyword">int</span>[] nums) &#123;</span><br><span class="line">    List&lt;List&lt;Integer&gt;&gt; queue=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (nums==<span class="keyword">null</span> || nums.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> queue;</span><br><span class="line">    &#125;</span><br><span class="line">    queue.add(<span class="keyword">new</span> ArrayList());</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.length;i++) &#123;</span><br><span class="line">        <span class="keyword">int</span> next=queue.size();</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;next;j++) &#123;</span><br><span class="line">            List&lt;Integer&gt; temp=<span class="keyword">new</span> ArrayList(queue.get(j));</span><br><span class="line">            temp.add(nums[i]);</span><br><span class="line">            queue.add(temp);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> queue;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法三（UPDATE: 2020.9.11）</strong></p>
<p>二进制枚举子集</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">subsets</span><span class="params">(nums []<span class="keyword">int</span>)</span> [][]<span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> n = <span class="built_in">len</span>(nums)</span><br><span class="line">    <span class="keyword">var</span> res [][]<span class="keyword">int</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; (<span class="number">1</span>&lt;&lt;n); i++ &#123;</span><br><span class="line">        <span class="keyword">var</span> lis []<span class="keyword">int</span></span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt; n; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> i &amp; (<span class="number">1</span>&lt;&lt;j) != <span class="number">0</span> &#123;</span><br><span class="line">                lis = <span class="built_in">append</span>(lis, nums[j])</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        res = <span class="built_in">append</span>(res, lis)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="90-子集-II"><a href="#90-子集-II" class="headerlink" title="90. 子集 II"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/subsets-ii/" >90. 子集 II<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个<strong>可能包含重复元素</strong>的整数数组 nums，返回该数组所有可能的子集（幂集）。</p>
<p><strong>说明：</strong>解集不能包含重复的子集。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">2</span>,<span class="number">2</span>]</span><br><span class="line">输出:</span><br><span class="line">[</span><br><span class="line">  [<span class="number">2</span>],</span><br><span class="line">  [<span class="number">1</span>],</span><br><span class="line">  [<span class="number">1</span>,<span class="number">2</span>,<span class="number">2</span>],</span><br><span class="line">  [<span class="number">2</span>,<span class="number">2</span>],</span><br><span class="line">  [<span class="number">1</span>,<span class="number">2</span>],</span><br><span class="line">  []</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>和40题很类似，主要就是这个去重的操作，比如题目给的case，<code>[1,2,2]</code> 已经有序了，在选择第一个2的时候其实就已经将所有包含2的子集都求出来了，后面的2就可以直接跳过，当然这里1，2，2本身就是有序的，试想如果是<code>2,1,2</code> 遍历第一个2会将所有包含2的子集求出来，但是遍历到1的时候会将第三个2包含进来，也就是<code>1，2</code> 这个解，但是前面已经求出了<code>[2,1]</code> 这就重复了，排序就是为了将相同的元素聚合到一起，这样遇到相同的元素就跳过，后面的元素就不会再包含已经遍历过的元素了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; subsetsWithDup(<span class="keyword">int</span>[] nums) &#123;</span><br><span class="line">    <span class="keyword">if</span> (nums==<span class="keyword">null</span> || nums.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//需要先排序，便于跳过相同的元素</span></span><br><span class="line">    Arrays.sort(nums);</span><br><span class="line">    subsets(nums,<span class="number">0</span>,<span class="keyword">new</span> ArrayList());</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span>  List&lt;List&lt;Integer&gt;&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">subsets</span><span class="params">(<span class="keyword">int</span>[] nums,<span class="keyword">int</span> index,List&lt;Integer&gt; lis)</span> </span>&#123;</span><br><span class="line">    res.add(<span class="keyword">new</span> ArrayList(lis));</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=index;i&lt;nums.length;i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (i&gt;index &amp;&amp; nums[i] == nums[i-<span class="number">1</span>]) &#123;</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        lis.add(nums[i]);</span><br><span class="line">        subsets(nums,i+<span class="number">1</span>,lis);</span><br><span class="line">        lis.remove(lis.size()-<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>Update: 2020.6.20</strong></p>
<p>用go重写了一遍，复习下</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">subsetsWithDup</span><span class="params">(nums []<span class="keyword">int</span>)</span> [][]<span class="title">int</span></span> &#123;</span><br><span class="line">    sort.Ints(nums)</span><br><span class="line">    <span class="keyword">var</span> res [][]<span class="keyword">int</span></span><br><span class="line">    <span class="keyword">var</span> lis []<span class="keyword">int</span></span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(index <span class="keyword">int</span>)</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(index <span class="keyword">int</span>)</span></span>&#123;</span><br><span class="line">        dest:=<span class="built_in">make</span>([]<span class="keyword">int</span>,<span class="built_in">len</span>(lis))</span><br><span class="line">        <span class="built_in">copy</span>(dest,lis)</span><br><span class="line">        res=<span class="built_in">append</span>(res,dest)</span><br><span class="line">        <span class="keyword">for</span> i:=index;i&lt;<span class="built_in">len</span>(nums);i++&#123;</span><br><span class="line">            <span class="keyword">if</span> i&gt;index &amp;&amp; nums[i]==nums[i<span class="number">-1</span>]&#123;</span><br><span class="line">                <span class="keyword">continue</span></span><br><span class="line">            &#125;</span><br><span class="line">            lis=<span class="built_in">append</span>(lis,nums[i])</span><br><span class="line">            dfs(i+<span class="number">1</span>)</span><br><span class="line">            lis=lis[:<span class="built_in">len</span>(lis)<span class="number">-1</span>]</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(<span class="number">0</span>)</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="357-计算各个位数不同的数字个数"><a href="#357-计算各个位数不同的数字个数" class="headerlink" title="357. 计算各个位数不同的数字个数"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/count-numbers-with-unique-digits/" >357. 计算各个位数不同的数字个数<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个非负整数 n，计算各位数字都不同的数字 x 的个数，其中 0 ≤ x &lt; 10n 。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="number">2</span></span><br><span class="line">输出: <span class="number">91</span> </span><br><span class="line">解释: 答案应为除去 <span class="number">11</span>,<span class="number">22</span>,<span class="number">33</span>,<span class="number">44</span>,<span class="number">55</span>,<span class="number">66</span>,<span class="number">77</span>,<span class="number">88</span>,<span class="number">99</span> 外，在 [<span class="number">0</span>,<span class="number">100</span>) 区间内的所有数字。</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<blockquote>
<p>这里要存个疑问，这里的回溯记忆化应该是错的，可能是数据太少了，没测试出来，但是居然真的提高了效率。。。。这就很诡异</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//这种可以做记忆化,0ms</span></span><br><span class="line">Integer[] cache=<span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">countNumbersWithUniqueDigits2</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">boolean</span>[] visit=<span class="keyword">new</span> <span class="keyword">boolean</span>[<span class="number">10</span>];</span><br><span class="line">    cache=<span class="keyword">new</span> Integer[n+<span class="number">1</span>];</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">if</span> (n==<span class="number">0</span>) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;=<span class="number">9</span>;i++) &#123; <span class="comment">//不考虑0开头的</span></span><br><span class="line">        visit[i]=<span class="keyword">true</span>;</span><br><span class="line">        res+=countNumbersWithUniqueDigits2(n,visit,<span class="number">1</span>);</span><br><span class="line">        visit[i]=<span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res+<span class="number">1</span>; <span class="comment">//加的是0这种情况</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//[index,n](位数)区间内,能构成最多的不重复数字</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">countNumbersWithUniqueDigits2</span><span class="params">(<span class="keyword">int</span> n,<span class="keyword">boolean</span>[] visit,<span class="keyword">int</span> index)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (index==n) &#123; <span class="comment">//没得选,只有一种</span></span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (cache[index]!=<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> cache[index];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> count=<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;=<span class="number">9</span>;i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!visit[i]) &#123;</span><br><span class="line">            visit[i]=<span class="keyword">true</span>;</span><br><span class="line">            count+=countNumbersWithUniqueDigits2(n,visit,index+<span class="number">1</span>);</span><br><span class="line">            visit[i]=<span class="keyword">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> cache[index]=count;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>我都不好意思放到回溯专题中，开始写了个贼脑残的回溯451ms，实在不好意思放上来</p>
<p><strong>解法二</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//数学方法(初中数学)</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">countNumbersWithUniqueDigits3</span><span class="params">(<span class="keyword">int</span> n)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (n==<span class="number">0</span>) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">if</span> (n&gt;<span class="number">10</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">10</span>,count=<span class="number">9</span>; <span class="comment">//i=1的情况</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">2</span>;i&lt;=n;i++) &#123;</span><br><span class="line">        count*=(<span class="number">11</span>-i); <span class="comment">//9*9*8*7*6*5.....</span></span><br><span class="line">        res+=count;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>说实话，这种方法我一开始写第一种很脑残的回溯的时候推出来了的，但是我居然没意识到。。。。</p>
<h2 id="89-格雷编码"><a href="#89-格雷编码" class="headerlink" title="89. 格雷编码"></a>89. 格雷编码</h2><p>格雷编码是一个二进制数字系统，在该系统中，两个连续的数值仅有一个位数的差异。</p>
<p>给定一个代表编码总位数的非负整数 n，打印其格雷编码序列。格雷编码序列必须以 0 开头。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="number">2</span></span><br><span class="line">输出: [<span class="number">0</span>,<span class="number">1</span>,<span class="number">3</span>,<span class="number">2</span>]</span><br><span class="line">解释:</span><br><span class="line"><span class="number">00</span> - <span class="number">0</span></span><br><span class="line"><span class="number">01</span> - <span class="number">1</span></span><br><span class="line"><span class="number">11</span> - <span class="number">3</span></span><br><span class="line"><span class="number">10</span> - <span class="number">2</span></span><br><span class="line"></span><br><span class="line">对于给定的 n，其格雷编码序列并不唯一。</span><br><span class="line">例如，[<span class="number">0</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">1</span>] 也是一个有效的格雷编码序列。</span><br><span class="line"></span><br><span class="line"><span class="number">00</span> - <span class="number">0</span></span><br><span class="line"><span class="number">10</span> - <span class="number">2</span></span><br><span class="line"><span class="number">11</span> - <span class="number">3</span></span><br><span class="line"><span class="number">01</span> - <span class="number">1</span></span><br></pre></td></tr></table></figure>


<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="number">0</span></span><br><span class="line">输出: [<span class="number">0</span>]</span><br><span class="line">解释: 我们定义格雷编码序列必须以 <span class="number">0</span> 开头。</span><br><span class="line">     给定编码总位数为 n 的格雷编码序列，其长度为 2n。当 n = <span class="number">0</span> 时，长度为 <span class="number">20</span> = <span class="number">1</span>。</span><br><span class="line">     因此，当 n = <span class="number">0</span> 时，其格雷编码序列为 [<span class="number">0</span>]。</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>又一个脑残做法。。。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">grayCode3</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    res.add(<span class="number">0</span>);</span><br><span class="line">    <span class="keyword">int</span> max=(<span class="number">1</span>&lt;&lt;n)-<span class="number">1</span>; <span class="comment">//注意优先级</span></span><br><span class="line">    <span class="keyword">boolean</span>[] visit=<span class="keyword">new</span> <span class="keyword">boolean</span>[max+<span class="number">1</span>];</span><br><span class="line">    grayCode3(max,res,visit);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">grayCode3</span><span class="params">(<span class="keyword">int</span> max,List&lt;Integer&gt; lis,<span class="keyword">boolean</span>[] visit)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (lis.size()&gt;max) &#123; <span class="comment">// list.size()==max+1 eg. when max=3 the list.size()=4</span></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> last=lis.get(lis.size()-<span class="number">1</span>);</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;=max;i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!visit[i] &amp;&amp; Integer.bitCount(i^last)==<span class="number">1</span>) &#123;</span><br><span class="line">            lis.add(i);</span><br><span class="line">            visit[i]=<span class="keyword">true</span>;</span><br><span class="line">            <span class="keyword">if</span>(grayCode3(max,lis,visit))&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            lis.remove(lis.size()-<span class="number">1</span>);</span><br><span class="line">            visit[i]=<span class="keyword">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>正常的回溯，每次修改一位，<strong>直接生成下一个可能的格雷码</strong>，而不是向上面一样一个个遍历。。。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//常规回溯</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">grayCode2</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">boolean</span>[] visit=<span class="keyword">new</span> <span class="keyword">boolean</span>[<span class="number">1</span>&lt;&lt;n];</span><br><span class="line">    res.add(<span class="number">0</span>);</span><br><span class="line">    visit[<span class="number">0</span>]=<span class="keyword">true</span>;</span><br><span class="line">    grayCode2(n,res,visit,<span class="number">0</span>);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">grayCode2</span><span class="params">(<span class="keyword">int</span> n,List&lt;Integer&gt; lis,<span class="keyword">boolean</span>[] visit,<span class="keyword">int</span> last)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (lis.size()&gt;=(<span class="number">1</span>&lt;&lt;n)) &#123; <span class="comment">// list.size()==max+1 eg. when max=3 the list.size()=4</span></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;n;i++) &#123;</span><br><span class="line">        <span class="comment">//直接生成下一个</span></span><br><span class="line">        <span class="keyword">int</span> next=last^(<span class="number">1</span>&lt;&lt;i); <span class="comment">//这一步其实就是从后往前,依次改变last一位</span></span><br><span class="line">        <span class="keyword">if</span> (!visit[next]) &#123;</span><br><span class="line">            lis.add(next);</span><br><span class="line">            visit[next]=<span class="keyword">true</span>;</span><br><span class="line">            <span class="keyword">if</span>(grayCode2(n,lis,visit,next))&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            lis.remove(lis.size()-<span class="number">1</span>);</span><br><span class="line">            visit[next]=<span class="keyword">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法三</strong></p>
<p>不停的和自己右移一位的值做异或，最终就可以的到完整的格雷码，至于原理并不想去研究😂，先记住再说</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//最优解,规律</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">grayCode</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;<span class="number">1</span>&lt;&lt;n;i++) &#123;</span><br><span class="line">        res.add(i^(i&gt;&gt;<span class="number">1</span>));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>看了评论区发现还有个规律，每一层的格雷码都是上一层前面加0 和逆序上一层在前面加1，感觉可能和上面的规律是一样的，一图以蔽之</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/blog/20191219/7rzdkpDvA4IN.png?imageslim"
                      alt="leetCode题解"
                ></p>
<h2 id="526-优美的排列"><a href="#526-优美的排列" class="headerlink" title="526. 优美的排列"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/beautiful-arrangement/" >526. 优美的排列<i class="fas fa-external-link-alt"></i></a></h2><p>假设有从 1 到 N 的 N 个整数，如果从这 N 个数字中成功构造出一个数组，使得数组的第 i 位 (1 &lt;= i &lt;= N) 满足如下两个条件中的一个，我们就称这个数组为一个优美的排列。条件：</p>
<ol>
<li>第 i 位的数字能被 i 整除</li>
<li>i 能被第 i 位上的数字整除</li>
</ol>
<p>现在给定一个整数 N，请问可以构造多少个优美的排列？</p>
<p><strong>解法一</strong></p>
<p>回溯法</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">countArrangement</span><span class="params">(<span class="keyword">int</span> N)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">boolean</span>[] visit=<span class="keyword">new</span> <span class="keyword">boolean</span>[N+<span class="number">1</span>];</span><br><span class="line">    <span class="keyword">return</span> countArrangement(N,visit,<span class="number">1</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">countArrangement</span><span class="params">(<span class="keyword">int</span> N,<span class="keyword">boolean</span>[] visit,<span class="keyword">int</span> index)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (index &gt; N) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;=N;i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!visit[i] &amp;&amp; (index%i==<span class="number">0</span> || i%index==<span class="number">0</span>)) &#123;</span><br><span class="line">            visit[i]=<span class="keyword">true</span>;</span><br><span class="line">            res+=countArrangement(N,visit,index+<span class="number">1</span>);</span><br><span class="line">            visit[i]=<span class="keyword">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>其实我是想改成记忆化递归的，不然我也不会这样写，但是后面改的时候居然出了bug，这也算是打醒了我，我一直以为这样的回溯都能改成记忆化递归。。。这里很明显无法做记忆化，因为你每次回溯的时候index相同，但是visit数组的状态是不一样的，直接记忆化肯定就错了。。。但是说到这里我发现上面的 <a href="##">357.各个位数不同数字个数</a> 居然这样过了，并且还真的提高了效率。。。。</p>
<h2 id="784-字母大小写全排列"><a href="#784-字母大小写全排列" class="headerlink" title="784. 字母大小写全排列"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/letter-case-permutation/" >784. 字母大小写全排列<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个字符串S，通过将字符串S中的每个字母转变大小写，我们可以获得一个新的字符串。返回所有可能得到的字符串集合。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: S = <span class="string">&quot;a1b2&quot;</span></span><br><span class="line">输出: [<span class="string">&quot;a1b2&quot;</span>, <span class="string">&quot;a1B2&quot;</span>, <span class="string">&quot;A1b2&quot;</span>, <span class="string">&quot;A1B2&quot;</span>]</span><br><span class="line"></span><br><span class="line">输入: S = <span class="string">&quot;3z4&quot;</span></span><br><span class="line">输出: [<span class="string">&quot;3z4&quot;</span>, <span class="string">&quot;3Z4&quot;</span>]</span><br><span class="line"></span><br><span class="line">输入: S = <span class="string">&quot;12345&quot;</span></span><br><span class="line">输出: [<span class="string">&quot;12345&quot;</span>]</span><br></pre></td></tr></table></figure>

<p><strong>注意：</strong></p>
<ul>
<li>S 的长度不超过12。</li>
<li>S 仅由数字和字母组成。 </li>
</ul>
<p><strong>解法一</strong></p>
<p>一看是简单题，屁颠屁颠就开始搞，结果发现没想象中简单（主要是我太菜了）</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> List&lt;String&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;String&gt; <span class="title">letterCasePermutation</span><span class="params">(String S)</span> </span>&#123;</span><br><span class="line">    letterCasePermutation(S,<span class="number">0</span>,<span class="keyword">new</span> StringBuilder(S));</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">letterCasePermutation</span><span class="params">(String S,<span class="keyword">int</span> index,StringBuilder cur)</span> </span>&#123;</span><br><span class="line">    res.add(cur.toString()); <span class="comment">//变化一次就添加一次</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=index;i&lt;S.length();i++) &#123;</span><br><span class="line">        <span class="keyword">char</span> c=S.charAt(i);</span><br><span class="line">        <span class="keyword">if</span> (c&gt;=<span class="string">&#x27;0&#x27;</span> &amp;&amp; c&lt;=<span class="string">&#x27;9&#x27;</span>) &#123;</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        cur.replace(i,i+<span class="number">1</span>,letterCase(c));</span><br><span class="line">        letterCasePermutation(S,i+<span class="number">1</span>,cur);</span><br><span class="line">        cur.replace(i,i+<span class="number">1</span>,letterCase(cur.charAt(i))); <span class="comment">//状态重置</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//这里其实有一个小技巧：c^(1&lt;&lt;5)就可以使大写变小写,小写变大写</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">letterCase</span><span class="params">(<span class="keyword">char</span> c)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (c&gt;=<span class="string">&#x27;a&#x27;</span> &amp;&amp; c&lt;=<span class="string">&#x27;z&#x27;</span>) &#123; <span class="comment">//65:A 97:a</span></span><br><span class="line">        c-=<span class="number">32</span>;</span><br><span class="line">    &#125;<span class="keyword">else</span> <span class="keyword">if</span> (c&gt;=<span class="string">&#x27;A&#x27;</span> &amp;&amp; c&lt;=<span class="string">&#x27;Z&#x27;</span>) &#123;</span><br><span class="line">        c+=<span class="number">32</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> c+<span class="string">&quot;&quot;</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这里的状态重置和之前的不太一样，不过整体还是很好想的，其实也可以完全不用循环的形式</p>
<h2 id="1079-活字印刷"><a href="#1079-活字印刷" class="headerlink" title="1079. 活字印刷"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/letter-tile-possibilities/" >1079. 活字印刷<i class="fas fa-external-link-alt"></i></a></h2><p>你有一套活字字模 tiles，其中每个字模上都刻有一个字母 tiles[i]。返回你可以印出的非空字母序列的数目。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：<span class="string">&quot;AAB&quot;</span></span><br><span class="line">输出：<span class="number">8</span></span><br><span class="line">解释：可能的序列为 <span class="string">&quot;A&quot;</span>, <span class="string">&quot;B&quot;</span>, <span class="string">&quot;AA&quot;</span>, <span class="string">&quot;AB&quot;</span>, <span class="string">&quot;BA&quot;</span>, <span class="string">&quot;AAB&quot;</span>, <span class="string">&quot;ABA&quot;</span>, <span class="string">&quot;BAA&quot;</span>。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：<span class="string">&quot;AAABBC&quot;</span></span><br><span class="line">输出：<span class="number">188</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li><code>1 &lt;= tiles.length &lt;= 7</code></li>
<li><code>tiles</code> 由大写英文字母组成</li>
</ol>
<p><strong>解法一</strong></p>
<p>这道题还是挺有意思的，有点结合全排列和子集的意思，</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">numTilePossibilities</span><span class="params">(String tiles)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">boolean</span>[] visit=<span class="keyword">new</span> <span class="keyword">boolean</span>[tiles.length()];</span><br><span class="line">    <span class="keyword">char</span>[] cs=tiles.toCharArray();</span><br><span class="line">    Arrays.sort(cs);</span><br><span class="line">    numTilePossibilities(cs,visit);</span><br><span class="line">    <span class="keyword">return</span> count;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> count=-<span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//排序去重</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">numTilePossibilities</span><span class="params">(<span class="keyword">char</span>[]cs,<span class="keyword">boolean</span>[] visit)</span> </span>&#123;</span><br><span class="line">    count++;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;cs.length;i++) &#123;</span><br><span class="line">        <span class="comment">//想清楚这里为啥必须是!visit[i-1]</span></span><br><span class="line">        <span class="keyword">if</span>(i&gt;<span class="number">0</span> &amp;&amp; cs[i]==cs[i-<span class="number">1</span>] &amp;&amp; !visit[i-<span class="number">1</span>])&#123; </span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (!visit[i]) &#123;</span><br><span class="line">            visit[i]=<span class="keyword">true</span>;</span><br><span class="line">            numTilePossibilities(cs,visit);</span><br><span class="line">            visit[i]=<span class="keyword">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这题收获比较大，对排列组合类型的题目又多了一层理解，同时也纠正了之前的错误观点</p>
<h3 id="Bug警告！！！"><a href="#Bug警告！！！" class="headerlink" title="Bug警告！！！"></a>Bug警告！！！</h3><p>看一下最开始写的错误解法，唯一的区别就在这个<code>!visit[i-1]</code>上！</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">if</span> (i&gt;<span class="number">0</span> &amp;&amp; cs[i]==cs[i-<span class="number">1</span>] &amp;&amp; visit[i-<span class="number">1</span>])</span><br></pre></td></tr></table></figure>

<p>这里我之前一直理解成了保留第一个分支，上一个元素已经访问过了，后面就直接跳过，做了这一题写出问题了才知道原来这里完全理解反了😂，当时没有仔细想，其实这里细想一下就很容易发现问题，visit数组其实保证的是当前这一条<strong>自上而下的纵向分支内不会有重复位置的元素被选取</strong>，而这里我们<strong>要确保的其实是横向的不重复，也就是同一层内不重复</strong>，所以这里使用<code>visit[i-1]</code> 其实从语义上来说就是有问题的，画个图来说明下为啥会有问题</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/blog/20200625/HekOxo1dFTYw.png?imageslim"
                      alt="mark"
                ></p>
<p>画个递归树，然后模拟一下，其实就明白了，使用<code>visit[i-1]</code>的方式，生成的第一个分支其实就不完整了，只有后面的第二个分支才会是完整的，所以<strong>可以理解为保留最后一个分支，将前面的分支剪掉</strong>，在全排列中因为有长度限制，第一个分支并没有达到给定的长度，所以并不会加入结果集，对结果没有影响，（其实是会影响效率的，会重复的遍历分支，这个打印一下生成全排列过程的结果集就能看出来）</p>
<p>但是在这一题，并没有长度的限制，所以count会将第一个不完整的分支也当作结果集算进去，而后面第二个分支的时候（完整分支）又会计算一遍，结果就错了</p>
<p><strong>那为什么<code>!visit[i-1]</code> 就可以呢？</strong></p>
<p>其实也很好理解，visit虽然保证的是纵向的不重复，但是每遍历完一个分支后，都会回溯状态，而我们又是<strong>按照顺序来遍历元素</strong>的，所以如果上一个元素的 visit[i]是false，那就说明上一个元素的分支已经遍历完了！以它开头的所有排列都找完了，这个时候我们判断是否相等然后跳过，才是真正的保留了第一个分支！后面的直接跳过，减少了多余的操作，同时也不会出现bug，所以你明白以后要用那个了吧😉</p>
<h2 id="1291-顺次数"><a href="#1291-顺次数" class="headerlink" title="1291. 顺次数"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/sequential-digits/" >1291. 顺次数<i class="fas fa-external-link-alt"></i></a></h2><p>我们定义「顺次数」为：每一位上的数字都比前一位上的数字大 1 的整数。</p>
<p>请你返回由 [low, high] 范围内所有顺次数组成的 有序 列表（从小到大排序）。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输出：low = <span class="number">100</span>, high = <span class="number">300</span></span><br><span class="line">输出：[<span class="number">123</span>,<span class="number">234</span>]</span><br></pre></td></tr></table></figure>


<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输出：low = <span class="number">1000</span>, high = <span class="number">13000</span></span><br><span class="line">输出：[<span class="number">1234</span>,<span class="number">2345</span>,<span class="number">3456</span>,<span class="number">4567</span>,<span class="number">5678</span>,<span class="number">6789</span>,<span class="number">12345</span>]</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>10 &lt;= low &lt;= high &lt;= 10^9 </li>
</ul>
<p><strong>解法一</strong></p>
<p>回溯tag下的，某一次周赛的题，我写的已经不像回溯了，尾递归，有点鸡肋</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">sequentialDigits</span><span class="params">(<span class="keyword">int</span> low, <span class="keyword">int</span> high)</span> </span>&#123;</span><br><span class="line">    String slow=String.valueOf(low);</span><br><span class="line">    <span class="keyword">int</span> slen=slow.length();</span><br><span class="line">    <span class="keyword">int</span> first=Integer.valueOf(slow.charAt(<span class="number">0</span>))-<span class="string">&#x27;0&#x27;</span>-<span class="number">1</span>;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">int</span> start=first,len=slen;</span><br><span class="line">    <span class="keyword">if</span>(first+len&gt;<span class="number">9</span>)&#123;</span><br><span class="line">        start=<span class="number">0</span>;</span><br><span class="line">        len++;</span><br><span class="line">    &#125;</span><br><span class="line">    sequentialDigits(low,high,start,len,res);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> String str=<span class="string">&quot;123456789&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sequentialDigits</span><span class="params">(<span class="keyword">int</span> low,<span class="keyword">int</span> high,<span class="keyword">int</span> start,<span class="keyword">int</span> len,List&lt;Integer&gt; list)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(start+len&gt;<span class="number">9</span>) <span class="keyword">return</span>;</span><br><span class="line">    <span class="keyword">int</span> cur=Integer.valueOf(str.substring(start,start+len));</span><br><span class="line">    <span class="keyword">if</span>(cur&gt;high)&#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(cur&gt;=low)&#123;</span><br><span class="line">        list.add(cur);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(start+len==<span class="number">9</span>)&#123;</span><br><span class="line">        sequentialDigits(low,high,<span class="number">0</span>,len+<span class="number">1</span>,list);    </span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        sequentialDigits(low,high,start+<span class="number">1</span>,len,list);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>其实直接暴力枚举<code>1~9</code>的所有顺序组合然后判断在不在<code>low~high</code> 之间就ok了，最再排个序就ok，一共也只有36个，个人感觉我上面的还是比单纯的暴力会好一点，首先不用排序，其次也不会从头开始遍历，会根据low的值来选取从哪里开始截取，但是这题数据量有限，体现不出来差异</p>
<h2 id="22-括号生成"><a href="#22-括号生成" class="headerlink" title="22. 括号生成"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/generate-parentheses/" >22. 括号生成<i class="fas fa-external-link-alt"></i></a></h2><p>给出 n 代表生成括号的对数，请你写出一个函数，使其能够生成所有可能的并且有效的括号组合。</p>
<p>例如，给出 <code>n = 3</code>，生成结果为：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">[</span><br><span class="line">  <span class="string">&quot;((()))&quot;</span>,</span><br><span class="line">  <span class="string">&quot;(()())&quot;</span>,</span><br><span class="line">  <span class="string">&quot;(())()&quot;</span>,</span><br><span class="line">  <span class="string">&quot;()(())&quot;</span>,</span><br><span class="line">  <span class="string">&quot;()()()&quot;</span></span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>哎，知道是回溯还是没做出来，还是太菜了啊</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;String&gt; <span class="title">generateParenthesis</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">    dfs(n,<span class="string">&quot;&quot;</span>,<span class="number">0</span>,<span class="number">0</span>);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> List&lt;String&gt; res=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span> n,String sb,<span class="keyword">int</span> left,<span class="keyword">int</span> right)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (left&gt;n <span class="comment">/*|| right&gt;n*/</span> || right&gt;left) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (left==n &amp;&amp; right ==n) &#123;</span><br><span class="line">        res.add(sb.toString());   </span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(n,sb+<span class="string">&quot;(&quot;</span>,left+<span class="number">1</span>,right);</span><br><span class="line">    dfs(n,sb+<span class="string">&quot;)&quot;</span>,left,right+<span class="number">1</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>关键还是没想明白这题的递归条件，我知道是先生成 “(“ 再生成 “)” 但是终止条件一直没想清楚，其实我们需要给左右括号加一个计数器<code>left和right</code>，用来记录已经生成的左右括号的数量，然后我们思考终止条件是啥，首先很容易想到的就是左右括号数量 <code>left==right</code> 的时候，这是合法的终止条件，但是这样就够了么？很明显不够，<code>()))((</code> 类似这样的就并不是合法的，所以我们还需要保证生成括号的合法性，所以这种时候若是不太清楚的就可以来画一画递归树</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/blog/20191024/9uvjEQzjtKtf.png?imageslim"
                      alt="mark"
                ></p>
<p>图画的比较魔性，但是还是很容易看懂的，通过这个递归树我还发现了上面代码的一点小问题，<code>right&gt;n</code> 是个冗余条件，合法条件 <code>right&lt; left &lt; n</code>，right肯定不会超过n，正如上面三个画 ❌的地方就是对应的三个不合法的终止条件，有了这个就可以很容易的写出回溯代码，下面的是用的<code>StringBuilder</code>的，需要回溯字符串，更符合回溯的思想，上面的String是不可变对象，所以不需要手动回溯</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;String&gt; <span class="title">generateParenthesis</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">    dfs(n,<span class="keyword">new</span> StringBuilder(),<span class="number">0</span>,<span class="number">0</span>);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> List&lt;String&gt; res=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span> n,StringBuilder sb,<span class="keyword">int</span> left,<span class="keyword">int</span> right)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (left&gt;n || right&gt;n || right&gt;left) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (left==n &amp;&amp; right ==n) &#123;</span><br><span class="line">        res.add(sb.toString());</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(n,sb.append(<span class="string">&quot;(&quot;</span>),left+<span class="number">1</span>,right);</span><br><span class="line">    sb.delete(sb.length()-<span class="number">1</span>,sb.length());</span><br><span class="line">    dfs(n,sb.append(<span class="string">&quot;)&quot;</span>),left,right+<span class="number">1</span>);</span><br><span class="line">    sb.delete(sb.length()-<span class="number">1</span>,sb.length());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="306-累加数"><a href="#306-累加数" class="headerlink" title="306. 累加数"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/additive-number/" >306. 累加数<i class="fas fa-external-link-alt"></i></a></h2><p>累加数是一个字符串，组成它的数字可以形成累加序列。</p>
<p>一个有效的累加序列必须<strong>至少</strong>包含 3 个数。除了最开始的两个数以外，字符串中的其他数都等于它之前两个数相加的和。</p>
<p>给定一个只包含数字 <code>&#39;0&#39;-&#39;9&#39;</code> 的字符串，编写一个算法来判断给定输入是否是累加数。</p>
<p><strong>说明:</strong> 累加序列里的数不会以 0 开头，所以不会出现 <code>1, 2, 03</code> 或者 <code>1, 02, 3</code> 的情况。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="string">&quot;112358&quot;</span></span><br><span class="line">输出: <span class="keyword">true</span> </span><br><span class="line">解释: 累加序列为: <span class="number">1</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">5</span>, <span class="number">8</span> 。<span class="number">1</span> + <span class="number">1</span> = <span class="number">2</span>, <span class="number">1</span> + <span class="number">2</span> = <span class="number">3</span>, <span class="number">2</span> + <span class="number">3</span> = <span class="number">5</span>, <span class="number">3</span> + <span class="number">5</span> = <span class="number">8</span></span><br></pre></td></tr></table></figure>


<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="string">&quot;199100199&quot;</span></span><br><span class="line">输出: <span class="keyword">true</span> </span><br><span class="line">解释: 累加序列为: <span class="number">1</span>, <span class="number">99</span>, <span class="number">100</span>, <span class="number">199</span>。<span class="number">1</span> + <span class="number">99</span> = <span class="number">100</span>, <span class="number">99</span> + <span class="number">100</span> = <span class="number">199</span></span><br></pre></td></tr></table></figure>

<p><strong>进阶:</strong></p>
<ul>
<li>你如何处理一个溢出的过大的整数输入?</li>
</ul>
<p><strong>解法一</strong></p>
<p>在回溯专题里翻到的，说实话，case有点恶心</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isAdditiveNumber</span><span class="params">(String num)</span> </span>&#123;</span><br><span class="line">    LinkedList&lt;String&gt; list=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    list.add(<span class="string">&quot;-1&quot;</span>);</span><br><span class="line">    list.add(<span class="string">&quot;-1&quot;</span>);</span><br><span class="line">    <span class="keyword">return</span> dfs(num,<span class="number">0</span>,list);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">dfs</span><span class="params">(String num,<span class="keyword">int</span> index,List&lt;String&gt; list)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//System.out.println(list);</span></span><br><span class="line">    <span class="keyword">if</span> (index==num.length() &amp;&amp; list.size()&gt;<span class="number">4</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=index+<span class="number">1</span>;i&lt;=num.length();i++)&#123;</span><br><span class="line">        <span class="comment">//0开头应该直接break,除非是单独的0....</span></span><br><span class="line">        <span class="keyword">if</span> (num.charAt(index)==<span class="string">&#x27;0&#x27;</span> &amp;&amp; i&gt;index+<span class="number">1</span>) &#123; <span class="comment">//&quot;101&quot; .....</span></span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//剪枝</span></span><br><span class="line">        <span class="keyword">if</span> (i-index&gt;num.length()/<span class="number">2</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        String sub=num.substring(index,i);</span><br><span class="line">        String a=list.get(list.size()-<span class="number">1</span>);</span><br><span class="line">        String b=list.get(list.size()-<span class="number">2</span>);</span><br><span class="line">        list.add(sub);</span><br><span class="line">        <span class="keyword">if</span> ((<span class="string">&quot;-1&quot;</span>.equals(a)||<span class="string">&quot;-1&quot;</span>.equals(b) || addTwoStr(a,b).equals(sub)) &amp;&amp; dfs(num,i,list)) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        list.remove(list.size()-<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//大数相加</span></span><br><span class="line"><span class="function"><span class="keyword">private</span> String <span class="title">addTwoStr</span><span class="params">(String a,String b)</span></span>&#123;</span><br><span class="line">    StringBuilder res=<span class="keyword">new</span> StringBuilder();</span><br><span class="line">    <span class="keyword">int</span> aIdx=a.length()-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> bIdx=b.length()-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> temp=<span class="number">0</span>; <span class="comment">//进位</span></span><br><span class="line">    <span class="keyword">while</span>(aIdx&gt;=<span class="number">0</span> || bIdx&gt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">int</span> as=aIdx&gt;=<span class="number">0</span>?a.charAt(aIdx)-<span class="number">48</span>:<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> bs=bIdx&gt;=<span class="number">0</span>?b.charAt(bIdx)-<span class="number">48</span>:<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> sum=as+bs+temp;</span><br><span class="line">        temp=(sum)/<span class="number">10</span>;</span><br><span class="line">        res.append(sum%<span class="number">10</span>);</span><br><span class="line">        aIdx--;bIdx--;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (temp==<span class="number">1</span>) &#123;</span><br><span class="line">        res.append(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res.reverse().toString();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>回溯不难想到，这一类回溯咋说呢，属于 “一镜到底” 的那种，可以看看解数独的哪个解法，也是这样的（其实就是参考的那个）带一个boolean返回值，走到结尾走不通才会回溯，N皇后这种就不太一样，不管是否成功都会回溯，反正目前大致的感觉就是这样，后面遇到更多题型再来总结</p>
<p>不过感觉这题的关键不是回溯，而是边界的处理，首先是溢出的问题，我看见有进阶的就没考虑溢出，结果还是溢出了，而且溢出了两次！！！最后没办法，也不想用<code>BigInteger</code>就自己写了大数相加的逻辑</p>
<p>除了溢出的问题，这题需要注意 <code>0 </code> 在这个<code>0</code> 上也WA了一发，因为回溯还是在分割字符串，但是如果有0的话就不能随便的分割了，具体看代码就懂了</p>
<h2 id="842-将数组拆分成斐波那契序列"><a href="#842-将数组拆分成斐波那契序列" class="headerlink" title="842. 将数组拆分成斐波那契序列"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/split-array-into-fibonacci-sequence/" >842. 将数组拆分成斐波那契序列<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个数字字符串 S，比如 S = “123456579”，我们可以将它分成斐波那契式的序列 [123, 456, 579]。</p>
<p>形式上，斐波那契式序列是一个非负整数列表 F，且满足：</p>
<ul>
<li>0 &lt;= F[i] &lt;= 2^31 - 1，（也就是说，每个整数都符合 32 位有符号整数类型）；</li>
<li>F.length &gt;= 3；</li>
<li>对于所有的0 &lt;= i &lt; F.length - 2，都有 <code>F[i] + F[i+1] = F[i+2]</code> 成立。</li>
</ul>
<p>另外，请注意，将字符串拆分成小块时，每个块的数字一定不要以零开头，除非这个块是数字 0 本身。</p>
<p>返回从 S 拆分出来的所有斐波那契式的序列块，如果不能拆分则返回 <code>[]</code>。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：<span class="string">&quot;123456579&quot;</span></span><br><span class="line">输出：[<span class="number">123</span>,<span class="number">456</span>,<span class="number">579</span>]</span><br></pre></td></tr></table></figure>


<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="string">&quot;11235813&quot;</span></span><br><span class="line">输出: [<span class="number">1</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">5</span>,<span class="number">8</span>,<span class="number">13</span>]</span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">输入: &quot;112358130&quot;</span><br><span class="line">输出: []</span><br><span class="line">解释: 这项任务无法完成。</span><br></pre></td></tr></table></figure>

<p><strong>示例 4：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：<span class="string">&quot;0123&quot;</span></span><br><span class="line">输出：[]</span><br><span class="line">解释：每个块的数字不能以零开头，因此 <span class="string">&quot;01&quot;</span>，<span class="string">&quot;2&quot;</span>，<span class="string">&quot;3&quot;</span> 不是有效答案。</span><br></pre></td></tr></table></figure>


<p><strong>示例 5：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="string">&quot;1101111&quot;</span></span><br><span class="line">输出: [<span class="number">110</span>, <span class="number">1</span>, <span class="number">111</span>]</span><br><span class="line">解释: 输出 [<span class="number">11</span>,<span class="number">0</span>,<span class="number">11</span>,<span class="number">11</span>] 也同样被接受。</span><br></pre></td></tr></table></figure>


<p><strong>提示：</strong></p>
<ul>
<li><code>1 &lt;= S.length &lt;= 200</code></li>
<li>字符串 S 中只含有数字。</li>
</ul>
<p><strong>解法一</strong></p>
<p>和上面那题一样，但是这题会简单一点，不用处理大数相加的情况，同时限定了数字的范围就是32位int，所以只要范围超过了int32就直接break</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">splitIntoFibonacci</span><span class="params">(String S)</span> </span>&#123;</span><br><span class="line">    LinkedList&lt;Integer&gt; res=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    dfs(S,<span class="number">0</span>,res);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">dfs</span><span class="params">(String S,<span class="keyword">int</span> index,List&lt;Integer&gt; lis)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (index == S.length()) &#123;</span><br><span class="line">        <span class="keyword">return</span> lis.size()&gt;<span class="number">2</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=index+<span class="number">1</span>;i&lt;=S.length();i++) &#123;</span><br><span class="line">        String temp=S.substring(index,i);</span><br><span class="line">        <span class="comment">//长度大于10,或者Long解析出来大于INT_MAX了就直接break</span></span><br><span class="line">        <span class="keyword">if</span> (S.charAt(index) == <span class="string">&#x27;0&#x27;</span> &amp;&amp; i&gt;index+<span class="number">1</span> || temp.length()&gt;<span class="number">10</span> || Long.valueOf(temp)&gt;Integer.MAX_VALUE) &#123;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">int</span> str=Integer.valueOf(temp);</span><br><span class="line">        <span class="keyword">int</span> one=lis.size()&gt;=<span class="number">2</span> ? lis.get(lis.size()-<span class="number">1</span>):-<span class="number">1</span>;</span><br><span class="line">        <span class="keyword">int</span> two=lis.size()&gt;=<span class="number">2</span> ? lis.get(lis.size()-<span class="number">2</span>):-<span class="number">1</span>;</span><br><span class="line">        lis.add(str);</span><br><span class="line">        <span class="keyword">if</span> ((one==-<span class="number">1</span> || two==-<span class="number">1</span> || one+two==str) &amp;&amp; dfs(S,i,lis)) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        lis.remove(lis.size()-<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="139-单词拆分"><a href="#139-单词拆分" class="headerlink" title="139. 单词拆分"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/word-break/" >139. 单词拆分<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict，判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。</p>
<p><strong>说明：</strong></p>
<ul>
<li>拆分时可以重复使用字典中的单词。</li>
<li>你可以假设字典中没有重复的单词。</li>
</ul>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: s = <span class="string">&quot;leetcode&quot;</span>, wordDict = [<span class="string">&quot;leet&quot;</span>, <span class="string">&quot;code&quot;</span>]</span><br><span class="line">输出: <span class="keyword">true</span></span><br><span class="line">解释: 返回 <span class="keyword">true</span> 因为 <span class="string">&quot;leetcode&quot;</span> 可以被拆分成 <span class="string">&quot;leet code&quot;</span>。</span><br></pre></td></tr></table></figure>


<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: s = <span class="string">&quot;applepenapple&quot;</span>, wordDict = [<span class="string">&quot;apple&quot;</span>, <span class="string">&quot;pen&quot;</span>]</span><br><span class="line">输出: <span class="keyword">true</span></span><br><span class="line">解释: 返回 <span class="keyword">true</span> 因为 <span class="string">&quot;applepenapple&quot;</span> 可以被拆分成 <span class="string">&quot;apple pen apple&quot;</span>。</span><br><span class="line">     注意你可以重复使用字典中的单词。</span><br></pre></td></tr></table></figure>


<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: s = <span class="string">&quot;catsandog&quot;</span>, wordDict = [<span class="string">&quot;cats&quot;</span>, <span class="string">&quot;dog&quot;</span>, <span class="string">&quot;sand&quot;</span>, <span class="string">&quot;and&quot;</span>, <span class="string">&quot;cat&quot;</span>]</span><br><span class="line">输出: <span class="keyword">false</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>回溯DFS+记忆化</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">Boolean[] cache=<span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">wordBreak</span><span class="params">(String s, List&lt;String&gt; wordDict)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (s==<span class="keyword">null</span> || s.length()&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    cache=<span class="keyword">new</span> Boolean[s.length()];</span><br><span class="line">    HashSet&lt;String&gt; set=<span class="keyword">new</span> HashSet&lt;&gt;(wordDict);</span><br><span class="line">    <span class="keyword">return</span> dfs(s,set,<span class="number">0</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//判断【index,s.len】中的字符是否能拆分</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">dfs</span><span class="params">(String s, HashSet&lt;String&gt; dict,<span class="keyword">int</span> index)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//这里的终止条件还是有点迷惑的,这里index只有在字典中存在当前元素的时候才会向后移动</span></span><br><span class="line">    <span class="comment">//所以当index移动到s==length的是偶就说明前面的单词都匹配上了</span></span><br><span class="line">    <span class="keyword">if</span> (index==s.length()) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (cache[index]!=<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> cache[index];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=index+<span class="number">1</span>;i&lt;=s.length();i++) &#123;</span><br><span class="line">        <span class="comment">//System.out.println(s.substring(index,i));</span></span><br><span class="line">        <span class="keyword">if</span> (dict.contains(s.substring(index,i)) &amp;&amp; dfs(s,dict,i))&#123;</span><br><span class="line">            <span class="keyword">return</span> cache[index]=<span class="keyword">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> cache[index]=<span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>很久之前做的题目，在做这题进阶版的时候发现这一题做了但是没有记录。。。可能是忘了</p>
<p>这里回溯记忆化没啥好说的，也是属于那种 “一镜到底” 类型的</p>
<p><strong>解法二</strong></p>
<p>BFS</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//BFS,需要一个visit保证不会重复访问</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">wordBreak</span><span class="params">(String s, List&lt;String&gt; wordDict)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (s==<span class="keyword">null</span> || s.length()&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    HashSet&lt;String&gt; dict=<span class="keyword">new</span> HashSet&lt;&gt;(wordDict);</span><br><span class="line">    <span class="comment">//queue中存index</span></span><br><span class="line">    LinkedList&lt;Integer&gt; queue=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    <span class="keyword">boolean</span>[] visit=<span class="keyword">new</span> <span class="keyword">boolean</span>[s.length()];</span><br><span class="line">    queue.add(<span class="number">0</span>);</span><br><span class="line">    <span class="keyword">while</span>(!queue.isEmpty())&#123;</span><br><span class="line">        <span class="keyword">int</span> index=queue.poll();</span><br><span class="line">        <span class="keyword">if</span> (!visit[index]) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> i=index+<span class="number">1</span>;i&lt;=s.length();i++) &#123;</span><br><span class="line">                <span class="keyword">if</span>(dict.contains(s.substring(index,i)))&#123;</span><br><span class="line">                    <span class="keyword">if</span> (i==s.length()) &#123;</span><br><span class="line">                        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">                    &#125;</span><br><span class="line">                    queue.add(i);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            visit[index]=<span class="keyword">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>自己写的居然一点印象都没有，BFS感觉也没啥好说的</p>
<p><strong>解法三</strong></p>
<p>动态规划，这个当时没有写出来，今天重新看的时候发现有dp的tag就写了一下，还是挺简单的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">wordBreak</span><span class="params">(String s, List&lt;String&gt; wordDict)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (s==<span class="keyword">null</span> || s.length()&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    HashSet&lt;String&gt; dict=<span class="keyword">new</span> HashSet&lt;&gt;(wordDict);</span><br><span class="line">    <span class="keyword">boolean</span>[] dp=<span class="keyword">new</span> <span class="keyword">boolean</span>[s.length()+<span class="number">1</span>];</span><br><span class="line">    dp[<span class="number">0</span>]=<span class="keyword">true</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;=s.length();i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;=i;j++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (dp[j] &amp;&amp; dict.contains(s.substring(j,i))) &#123;</span><br><span class="line">               dp[i]=<span class="keyword">true</span>; <span class="comment">//相比上面的可以break</span></span><br><span class="line">               <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[s.length()];</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="140-单词拆分-II"><a href="#140-单词拆分-II" class="headerlink" title="140. 单词拆分 II"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/word-break-ii/" >140. 单词拆分 II<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个<strong>非空</strong>字符串 s 和一个包含非空单词列表的字典 wordDict，在字符串中增加空格来构建一个句子，使得句子中所有的单词都在词典中。返回所有这些可能的句子。</p>
<p><strong>说明：</strong></p>
<ul>
<li>分隔时可以重复使用字典中的单词。</li>
<li>你可以假设字典中没有重复的单词。</li>
</ul>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">s = <span class="string">&quot;catsanddog&quot;</span></span><br><span class="line">wordDict = [<span class="string">&quot;cat&quot;</span>, <span class="string">&quot;cats&quot;</span>, <span class="string">&quot;and&quot;</span>, <span class="string">&quot;sand&quot;</span>, <span class="string">&quot;dog&quot;</span>]</span><br><span class="line">输出:</span><br><span class="line">[</span><br><span class="line">  <span class="string">&quot;cats and dog&quot;</span>,</span><br><span class="line">  <span class="string">&quot;cat sand dog&quot;</span></span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">s = <span class="string">&quot;pineapplepenapple&quot;</span></span><br><span class="line">wordDict = [<span class="string">&quot;apple&quot;</span>, <span class="string">&quot;pen&quot;</span>, <span class="string">&quot;applepen&quot;</span>, <span class="string">&quot;pine&quot;</span>, <span class="string">&quot;pineapple&quot;</span>]</span><br><span class="line">输出:</span><br><span class="line">[</span><br><span class="line">  <span class="string">&quot;pine apple pen apple&quot;</span>,</span><br><span class="line">  <span class="string">&quot;pineapple pen apple&quot;</span>,</span><br><span class="line">  <span class="string">&quot;pine applepen apple&quot;</span></span><br><span class="line">]</span><br><span class="line">解释: 注意你可以重复使用字典中的单词。</span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">s = <span class="string">&quot;catsandog&quot;</span></span><br><span class="line">wordDict = [<span class="string">&quot;cats&quot;</span>, <span class="string">&quot;dog&quot;</span>, <span class="string">&quot;sand&quot;</span>, <span class="string">&quot;and&quot;</span>, <span class="string">&quot;cat&quot;</span>]</span><br><span class="line">输出:</span><br><span class="line">[]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>这题要求出所有的序列，所以dp肯定是不好整了，直接上回溯</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;String&gt; <span class="title">wordBreak</span><span class="params">(String s, List&lt;String&gt; wordDict)</span> </span>&#123;</span><br><span class="line">    HashSet&lt;String&gt; dict=<span class="keyword">new</span> HashSet&lt;&gt;(wordDict);</span><br><span class="line">    dfs(s,<span class="number">0</span>,<span class="string">&quot;&quot;</span>,dict);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> List&lt;String&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(String s,<span class="keyword">int</span> index,String word,HashSet&lt;String&gt; dict)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (index==s.length()) &#123;</span><br><span class="line">        res.add(word.substring(<span class="number">0</span>,word.length()-<span class="number">1</span>));</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=index+<span class="number">1</span>;i&lt;=s.length();i++) &#123;</span><br><span class="line">        String str=s.substring(index,i);</span><br><span class="line">        <span class="keyword">if</span> (dict.contains(str)) &#123;</span><br><span class="line">            <span class="comment">//word.append(str+&quot; &quot;); // app#pa# </span></span><br><span class="line">            dfs(s,i,word+str+<span class="string">&quot; &quot;</span>,dict);</span><br><span class="line">            <span class="comment">//word.delete(word.length()-(i-),i);</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>很可惜，超时了，卡在了aaaaaaaa….那个case上，翻了评论区，发现很多人借用了上一题的解法，先对整个s做可行性分析，也就是看能不能拆分，能拆分然后再进行回溯，这样就刚好跳过了那个case，好像确实是可以过，但是我感觉有点面向case编程了。。。</p>
<p><strong>解法二</strong></p>
<p>记忆化回溯，上面的过程分析一下会发现其实有很多的重复计算，所以我们可以有针对性的做记忆化，加快搜索速度</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//做记忆化</span></span><br><span class="line">HashMap&lt;String,List&lt;String&gt;&gt; cache=<span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;String&gt; <span class="title">wordBreak</span><span class="params">(String s, List&lt;String&gt; wordDict)</span> </span>&#123;</span><br><span class="line">    HashSet&lt;String&gt; dict=<span class="keyword">new</span> HashSet&lt;&gt;(wordDict);</span><br><span class="line">    <span class="keyword">return</span> dfs(s,dict);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;String&gt; <span class="title">dfs</span><span class="params">(String s,HashSet&lt;String&gt; dict)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (cache.containsKey(s)) &#123;</span><br><span class="line">        <span class="keyword">return</span> cache.get(s);</span><br><span class="line">    &#125;</span><br><span class="line">    List&lt;String&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (s.length()==<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;=s.length();i++) &#123;</span><br><span class="line">        String word=s.substring(<span class="number">0</span>,i);</span><br><span class="line">        <span class="keyword">if</span> (dict.contains(word)) &#123;</span><br><span class="line">            <span class="keyword">if</span> (i==s.length()) &#123;</span><br><span class="line">                res.add(word);</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="comment">//剩余字符</span></span><br><span class="line">                List&lt;String&gt; temp=dfs(s.substring(i,s.length()),dict);</span><br><span class="line">                <span class="keyword">for</span> (String tmp:temp) &#123;</span><br><span class="line">                    res.add(word+<span class="string">&quot; &quot;</span>+tmp);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    cache.put(s,res);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>其实我这里也是参考了评论区的解法，我上面的那种回溯的方式要改成记忆化有点不好搞，有两个变量，另外我感觉这种<strong>回溯分割</strong>的方式感觉更加的直观易懂 get</p>
<p><strong>UPDATE: 2020.7.8</strong></p>
<p>偶然看到这个题，重写了一下，直接记忆化</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="comment">//记忆化递归</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">wordBreak</span><span class="params">(s <span class="keyword">string</span>, wordDict []<span class="keyword">string</span>)</span> []<span class="title">string</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> set = <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">string</span>]<span class="keyword">bool</span>)</span><br><span class="line">    <span class="keyword">var</span> cache = <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">string</span>][]<span class="keyword">string</span>)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="built_in">len</span>(wordDict); i++ &#123;</span><br><span class="line">        set[wordDict[i]] = <span class="literal">true</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dfs(s, set, cache)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">dfs</span><span class="params">(s <span class="keyword">string</span>, set <span class="keyword">map</span>[<span class="keyword">string</span>]<span class="keyword">bool</span>, cache <span class="keyword">map</span>[<span class="keyword">string</span>][]<span class="keyword">string</span>)</span> []<span class="title">string</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> _, ok := cache[s]; ok &#123;</span><br><span class="line">        <span class="keyword">return</span> cache[s]</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> res []<span class="keyword">string</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt;= <span class="built_in">len</span>(s); i++ &#123;</span><br><span class="line">        <span class="keyword">if</span> set[s[:i]] &#123;</span><br><span class="line">            <span class="keyword">if</span> i == <span class="built_in">len</span>(s) &#123;</span><br><span class="line">                res = <span class="built_in">append</span>(res, s[:i])</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                temp := dfs(s[i:], set, cache)</span><br><span class="line">                <span class="keyword">for</span> _, w := <span class="keyword">range</span> temp &#123;</span><br><span class="line">                    res = <span class="built_in">append</span>(res, s[:i]+<span class="string">&quot; &quot;</span>+w)</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    cache[s] = res</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="473-火柴拼正方形"><a href="#473-火柴拼正方形" class="headerlink" title="473. 火柴拼正方形"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/matchsticks-to-square/" >473. 火柴拼正方形<i class="fas fa-external-link-alt"></i></a></h2><p>还记得童话《卖火柴的小女孩》吗？现在，你知道小女孩有多少根火柴，请找出一种能使用所有火柴拼成一个正方形的方法。不能折断火柴，可以把火柴连接起来，并且每根火柴都要用到。</p>
<p>输入为小女孩拥有火柴的数目，每根火柴用其长度表示。输出即为是否能用所有的火柴拼成正方形。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>]</span><br><span class="line">输出: <span class="keyword">true</span></span><br><span class="line"></span><br><span class="line">解释: 能拼成一个边长为<span class="number">2</span>的正方形，每边两根火柴。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">3</span>,<span class="number">3</span>,<span class="number">3</span>,<span class="number">3</span>,<span class="number">4</span>]</span><br><span class="line">输出: <span class="keyword">false</span></span><br><span class="line"></span><br><span class="line">解释: 不能用所有火柴拼成一个正方形。</span><br></pre></td></tr></table></figure>

<p><strong>注意:</strong></p>
<ol>
<li>给定的火柴长度和在 <code>0</code> 到 <code>10^9</code>之间。</li>
<li>火柴数组的长度不超过15。</li>
</ol>
<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//等价于能否将nums分为4等分</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">makesquare</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(nums==<span class="keyword">null</span> || nums.length&lt;<span class="number">4</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> N=nums.length;</span><br><span class="line">    <span class="keyword">int</span> sum=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;N;i++)&#123;</span><br><span class="line">        sum+=nums[i];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(sum%<span class="number">4</span>!=<span class="number">0</span>) <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    <span class="keyword">int</span>[] side=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">4</span>];</span><br><span class="line">    Arrays.sort(nums);</span><br><span class="line">    <span class="keyword">return</span> dfs(nums,N-<span class="number">1</span>,side,sum/<span class="number">4</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span>[] nums,<span class="keyword">int</span> index,<span class="keyword">int</span>[] side,<span class="keyword">int</span> avg)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(index==-<span class="number">1</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;side.length;i++)&#123;</span><br><span class="line">        <span class="comment">//if(side[i]+nums[index]&lt;=avg)&#123;</span></span><br><span class="line">        <span class="keyword">int</span> rest=avg-side[i]-nums[index];</span><br><span class="line">        <span class="keyword">if</span>(rest==<span class="number">0</span> || rest&gt;=nums[<span class="number">0</span>])&#123; <span class="comment">//改进剪枝方式</span></span><br><span class="line">            side[i]+=nums[index];</span><br><span class="line">            <span class="keyword">if</span>(dfs(nums,index-<span class="number">1</span>,side,avg))&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            side[i]-=nums[index];</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>一开始没想到分桶的做法，只想着这么搜索4等分，看了一眼评论区就明白了，抽象出4条边，然后遍历所有火柴，尝试将火柴放入所有的盒子，看有没有一种可能是4等分的，说白了其实就是暴力搜索，然后加上一点剪枝优化，这题就不细说了，关键看下面这题</p>
<h2 id="698-划分为k个相等的子集"><a href="#698-划分为k个相等的子集" class="headerlink" title="698. 划分为k个相等的子集"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets/" >698. 划分为k个相等的子集<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个整数数组  <code>nums</code> 和一个正整数 <code>k</code>，找出是否有可能把这个数组分成 <code>k</code> 个非空子集，其总和都相等。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入： nums = [<span class="number">4</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">5</span>, <span class="number">2</span>, <span class="number">1</span>], k = <span class="number">4</span></span><br><span class="line">输出： True</span><br><span class="line">说明： 有可能将其分成 <span class="number">4</span> 个子集（<span class="number">5</span>），（<span class="number">1</span>,<span class="number">4</span>），（<span class="number">2</span>,<span class="number">3</span>），（<span class="number">2</span>,<span class="number">3</span>）等于总和。</span><br></pre></td></tr></table></figure>

<p><strong>注意:</strong></p>
<ul>
<li><code>1 &lt;= k &lt;= len(nums) &lt;= 16</code></li>
<li><code>0 &lt; nums[i] &lt; 10000</code></li>
</ul>
<p><strong>解法一</strong></p>
<p><a href="#473-%E7%81%AB%E6%9F%B4%E6%8B%BC%E6%AD%A3%E6%96%B9%E5%BD%A2">473. 火柴拼正方形</a>其实只是这道题的一个子问题，关键搞懂这题就行了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">canPartitionKSubsets</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(nums==<span class="keyword">null</span> || nums.length&lt;=<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> sum=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.length;i++)&#123;</span><br><span class="line">        sum+=nums[i];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(sum%k!=<span class="number">0</span>) <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    Arrays.sort(nums);</span><br><span class="line">    <span class="keyword">return</span> dfs(nums,nums.length-<span class="number">1</span>,<span class="keyword">new</span> <span class="keyword">int</span>[k],sum);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span>[] nums,<span class="keyword">int</span> index,<span class="keyword">int</span>[] bucket,<span class="keyword">int</span> sum)</span></span>&#123;</span><br><span class="line">    <span class="comment">//sum(bucket)==sum</span></span><br><span class="line">    <span class="comment">//if条件: bucket[i]&lt;=sum/bucket.len =&gt; bucket[i]&lt;=sum(bucket)/bucket.len</span></span><br><span class="line">    <span class="comment">//所以不用单独去判断是否都相等,直接retuen true</span></span><br><span class="line">    <span class="keyword">if</span>(index==-<span class="number">1</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;bucket.length;i++)&#123;</span><br><span class="line">        <span class="comment">//普通的剪枝 60ms，只判断了是否小于平均值</span></span><br><span class="line">        <span class="comment">//if(bucket[i]+nums[index]&lt;=sum/bucket.length)&#123;</span></span><br><span class="line">        <span class="comment">//更好的剪枝方式1ms，判断剩余空间不为0的时候还能不能填其他元素</span></span><br><span class="line">        <span class="keyword">int</span> rest=sum/bucket.length-bucket[i]-nums[index];</span><br><span class="line">        <span class="keyword">if</span>(rest==<span class="number">0</span> || rest&gt;=nums[<span class="number">0</span>])&#123; <span class="comment">//小于nums[0]就啥也填不了了</span></span><br><span class="line">            bucket[i]+=nums[index];</span><br><span class="line">            <span class="keyword">if</span>(dfs(nums,index-<span class="number">1</span>,bucket,sum))&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            bucket[i]-=nums[index];</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>其实总体上来说还是暴力的搜索，然后加上一些剪枝优化的手段，首先能想到的是<strong>约束桶内元素和要小于等于<code>sum/k</code>**，这样就能减去很多无效搜索，但是仅仅这样还是无法AC这题，还有一步很关键的优化点是</strong>排序**，排序后我们从大往小搜索，也就是优先将大的元素放入桶中，尽快满足if条件，经过上面的优化就可以成功的AC了，耗时60ms左右，但是看了评论区的大佬的解法后发现还有一种更好的剪枝方式，就是考虑放下当前元素后还能不能放下其他的元素，如果刚好放下就直接放，如果放下后还有剩余空间，且这个剩余空间很小，连<code>nums[0]</code>都放不下（前面排序了）那么这种情况也是可以直接剪掉的，时间优化到1ms</p>
<blockquote>
<p><code>index==-1</code>为什么就直接返回true了？简单推一下就行了</p>
<p>首先<code>index==-1</code>说明所有元素都已经放入<code>bucket</code>中了，所以<code>sum(bucket)=sum(nums)</code></p>
<p>再来看我们的if条件：约束桶内元素小于等于<code>sum/k</code>，也就是<code>bucket[i]&lt;=sum(nums)/k</code> 借助上面的结论，转换一下就是 <code>bucket[i]&lt;=sum(bucket)/k</code>也就是<code>bucket[i]&lt;=avg(bucket)</code>很明显，只有在每个桶内元素都相等的时候才成立，故这里可以直接返回true</p>
</blockquote>
<p><strong>解法二</strong></p>
<p>官方提供了一个状压的方法，但是没看懂，自己试着压了下没过，懒得去研究了</p>
<h2 id="491-递增子序列"><a href="#491-递增子序列" class="headerlink" title="491. 递增子序列"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/increasing-subsequences/" >491. 递增子序列<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>中等</strong></p>
<p>给定一个整型数组, 你的任务是找到所有该数组的递增子序列，递增子序列的长度至少是2。</p>
<p><strong>示例:</strong></p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">输入: [4, 6, 7, 7]</span><br><span class="line">输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]]</span><br></pre></td></tr></table></figure>

<p><strong>说明:</strong></p>
<ol>
<li> 给定数组的长度不会超过15。</li>
<li> 数组中的整数范围是 [-100,100]。</li>
<li> 给定数组中可能包含重复数字，相等的数字应该被视为递增的一种情况。</li>
</ol>
<p><strong>解法一</strong></p>
<p>感觉今天晚上状态不太好，好久没写回溯了，写了几发思路都有问题，最后瞄了一眼评论区才反应过来，和上面<a href="#842-%E5%B0%86%E6%95%B0%E7%BB%84%E6%8B%86%E5%88%86%E6%88%90%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E5%BA%8F%E5%88%97">842-将数组拆分成斐波那契序列</a>很类似，都是利用lis数组上次存值判断，当时这题还是我独立写出来的，写完发的code评论还是个热评，今天写这题居然没反应过来，太菜了😥</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">findSubsequences</span><span class="params">(nums []<span class="keyword">int</span>)</span> [][]<span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> n = <span class="built_in">len</span>(nums)</span><br><span class="line">    <span class="keyword">var</span> res [][]<span class="keyword">int</span></span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(<span class="keyword">int</span>, []<span class="keyword">int</span>)</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(index <span class="keyword">int</span>, lis []<span class="keyword">int</span>)</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">len</span>(lis) &gt;= <span class="number">2</span>&#123;</span><br><span class="line">            dest := <span class="built_in">make</span>([]<span class="keyword">int</span>, <span class="built_in">len</span>(lis))</span><br><span class="line">            <span class="built_in">copy</span>(dest, lis)</span><br><span class="line">            res = <span class="built_in">append</span>(res, dest)</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//保证一次for循环中没有重复的就行了，根据取值范围做下偏移</span></span><br><span class="line">        <span class="keyword">var</span> visit = <span class="built_in">make</span>([]<span class="keyword">bool</span>, <span class="number">201</span>)</span><br><span class="line">        <span class="keyword">for</span> i := index; i &lt; n; i++&#123;</span><br><span class="line">            <span class="keyword">if</span> !visit[nums[i]+<span class="number">100</span>] &amp;&amp; (<span class="built_in">len</span>(lis) == <span class="number">0</span> || nums[i] &gt;= lis[<span class="built_in">len</span>(lis)<span class="number">-1</span>]) &#123;</span><br><span class="line">                visit[nums[i]+<span class="number">100</span>] = <span class="literal">true</span></span><br><span class="line">                lis = <span class="built_in">append</span>(lis, nums[i])</span><br><span class="line">                dfs(i+<span class="number">1</span>, lis)</span><br><span class="line">                lis = lis[:<span class="built_in">len</span>(lis)<span class="number">-1</span>]</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(<span class="number">0</span>, <span class="built_in">make</span>([]<span class="keyword">int</span>, <span class="number">0</span>))</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="679-24-点游戏"><a href="#679-24-点游戏" class="headerlink" title="679. 24 点游戏"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/24-game/" >679. 24 点游戏<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>困难</strong></p>
<p>你有 4 张写有 1 到 9 数字的牌。你需要判断是否能通过 <code>*</code>，<code>/</code>，<code>+</code>，<code>-</code>，<code>(</code>，<code>)</code> 的运算得到 24。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">4</span>, <span class="number">1</span>, <span class="number">8</span>, <span class="number">7</span>]</span><br><span class="line">输出: True</span><br><span class="line">解释: (<span class="number">8</span><span class="number">-4</span>) * (<span class="number">7</span><span class="number">-1</span>) = <span class="number">24</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>, <span class="number">2</span>, <span class="number">1</span>, <span class="number">2</span>]</span><br><span class="line">输出: False</span><br></pre></td></tr></table></figure>

<p><strong>注意:</strong></p>
<ol>
<li> 除法运算符 <code>/</code> 表示实数除法，而不是整数除法。例如 4 / (1 - 2/3) = 12 。</li>
<li> 每个运算符对两个数进行运算。特别是我们不能用 <code>-</code> 作为一元运算符。例如，<code>[1, 1, 1, 1]</code> 作为输入时，表达式 <code>-1 - 1 - 1 - 1</code> 是不允许的。</li>
<li> 你不能将数字连接在一起。例如，输入为 <code>[1, 2, 1, 2]</code> 时，不能写成 12 + 12 。</li>
</ol>
<p><strong>解法一</strong></p>
<p>代码有点长，不过思路还是很清楚，一共4个数字，从里面任意选2个，然后做各种运算后和剩下的数字构成新的数组，然后重复该过程直到数组只剩下一个然后判断值是否是24（注意精度）</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">judgePoint24</span><span class="params">(nums []<span class="keyword">int</span>)</span> <span class="title">bool</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> eps <span class="keyword">float32</span> = <span class="number">1e-5</span></span><br><span class="line">    <span class="keyword">var</span> Abs = <span class="function"><span class="keyword">func</span><span class="params">(a <span class="keyword">float32</span>)</span> <span class="title">float32</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &lt; <span class="number">0</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> -a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//计数+-*/</span></span><br><span class="line">    <span class="keyword">var</span> compute = <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="keyword">float32</span>)</span> []<span class="title">float32</span></span> &#123;</span><br><span class="line">        <span class="keyword">return</span> []<span class="keyword">float32</span>&#123;a + b, a * b, a - b, a / b&#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">([]<span class="keyword">float32</span>)</span> <span class="title">bool</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(nums []<span class="keyword">float32</span>)</span> <span class="title">bool</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">len</span>(nums) == <span class="number">0</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">len</span>(nums) == <span class="number">1</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> Abs(nums[<span class="number">0</span>]<span class="number">-24</span>) &lt; eps</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">var</span> n = <span class="built_in">len</span>(nums)</span><br><span class="line">        <span class="comment">//从nums中选取2个数</span></span><br><span class="line">        <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">            <span class="keyword">for</span> j := <span class="number">0</span>; j &lt; n; j++ &#123;</span><br><span class="line">                <span class="keyword">if</span> i == j &#123;</span><br><span class="line">                    <span class="keyword">continue</span></span><br><span class="line">                &#125;</span><br><span class="line">                <span class="comment">//收集剩下的数字</span></span><br><span class="line">                <span class="keyword">var</span> rest []<span class="keyword">float32</span></span><br><span class="line">                <span class="keyword">for</span> k := <span class="number">0</span>; k &lt; n; k++ &#123;</span><br><span class="line">                    <span class="keyword">if</span> k != i &amp;&amp; k != j &#123;</span><br><span class="line">                        rest = <span class="built_in">append</span>(rest, nums[k])</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="comment">//尝试做各种运算</span></span><br><span class="line">                <span class="keyword">for</span> _, v := <span class="keyword">range</span> compute(nums[i], nums[j]) &#123;</span><br><span class="line">                    <span class="keyword">if</span> dfs(<span class="built_in">append</span>(rest, v)) &#123;</span><br><span class="line">                        <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> temp = <span class="built_in">make</span>([]<span class="keyword">float32</span>, <span class="built_in">len</span>(nums))</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="built_in">len</span>(nums); i++ &#123;</span><br><span class="line">        temp[i] = <span class="keyword">float32</span>(nums[i])</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dfs(temp)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="5526-最多可达成的换楼请求数目"><a href="#5526-最多可达成的换楼请求数目" class="headerlink" title="5526. 最多可达成的换楼请求数目"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/maximum-number-of-achievable-transfer-requests/" >5526. 最多可达成的换楼请求数目<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>困难</strong></p>
<p>我们有 <code>n</code> 栋楼，编号从 <code>0</code> 到 <code>n - 1</code> 。每栋楼有若干员工。由于现在是换楼的季节，部分员工想要换一栋楼居住。</p>
<p>给你一个数组 <code>requests</code> ，其中 requests[i] = [from<sub style="display: inline;">i</sub>, to<sub style="display: inline;">i</sub>] ，表示一个员工请求从编号为from<sub style="display: inline;">i</sub> 的楼搬到编号为 to<sub style="display: inline;">i</sub>的楼。</p>
<p>一开始 <strong>所有楼都是满的</strong>，所以从请求列表中选出的若干个请求是可行的需要满足 每栋楼员工净变化为 0 。意思是每栋楼 <strong>离开</strong> 的员工数目 <strong>等于</strong> 该楼 <strong>搬入</strong> 的员工数数目。比方说 <code>n = 3</code> 且两个员工要离开楼 <code>0</code> ，一个员工要离开楼 <code>1</code> ，一个员工要离开楼 <code>2</code> ，如果该请求列表可行，应该要有两个员工搬入楼 <code>0</code> ，一个员工搬入楼 <code>1</code> ，一个员工搬入楼 <code>2</code> 。</p>
<p>请你从原请求列表中选出若干个请求，使得它们是一个可行的请求列表，并返回所有可行列表中最大请求数目。</p>
<p><strong>示例 1：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/09/27/0AZHr8.png"
                      alt="0AZHr8.png"
                ></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：n = <span class="number">5</span>, requests = [[<span class="number">0</span>,<span class="number">1</span>],[<span class="number">1</span>,<span class="number">0</span>],[<span class="number">0</span>,<span class="number">1</span>],[<span class="number">1</span>,<span class="number">2</span>],[<span class="number">2</span>,<span class="number">0</span>],[<span class="number">3</span>,<span class="number">4</span>]]</span><br><span class="line">输出：<span class="number">5</span></span><br><span class="line">解释：请求列表如下：</span><br><span class="line">从楼 <span class="number">0</span> 离开的员工为 x 和 y ，且他们都想要搬到楼 <span class="number">1</span> 。</span><br><span class="line">从楼 <span class="number">1</span> 离开的员工为 a 和 b ，且他们分别想要搬到楼 <span class="number">2</span> 和 <span class="number">0</span> 。</span><br><span class="line">从楼 <span class="number">2</span> 离开的员工为 z ，且他想要搬到楼 <span class="number">0</span> 。</span><br><span class="line">从楼 <span class="number">3</span> 离开的员工为 c ，且他想要搬到楼 <span class="number">4</span> 。</span><br><span class="line">没有员工从楼 <span class="number">4</span> 离开。</span><br><span class="line">我们可以让 x 和 b 交换他们的楼，以满足他们的请求。</span><br><span class="line">我们可以让 y，a 和 z 三人在三栋楼间交换位置，满足他们的要求。</span><br><span class="line">所以最多可以满足 <span class="number">5</span> 个请求。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/09/27/0AZLVg.png"
                      alt="0AZLVg.png"
                ></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：n = <span class="number">3</span>, requests = [[<span class="number">0</span>,<span class="number">0</span>],[<span class="number">1</span>,<span class="number">2</span>],[<span class="number">2</span>,<span class="number">1</span>]]</span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释：请求列表如下：</span><br><span class="line">从楼 <span class="number">0</span> 离开的员工为 x ，且他想要回到原来的楼 <span class="number">0</span> 。</span><br><span class="line">从楼 <span class="number">1</span> 离开的员工为 y ，且他想要搬到楼 <span class="number">2</span> 。</span><br><span class="line">从楼 <span class="number">2</span> 离开的员工为 z ，且他想要搬到楼 <span class="number">1</span> 。</span><br><span class="line">我们可以满足所有的请求。</span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：n = <span class="number">4</span>, requests = [[<span class="number">0</span>,<span class="number">3</span>],[<span class="number">3</span>,<span class="number">1</span>],[<span class="number">1</span>,<span class="number">2</span>],[<span class="number">2</span>,<span class="number">0</span>]]</span><br><span class="line">输出：<span class="number">4</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>  1 &lt;= n &lt;= 20</li>
<li>  1 &lt;= requests.length &lt;= 16</li>
<li>  requests[i].length == 2</li>
<li>  0 &lt;= from<sub style="display: inline;">i</sub>, to<sub style="display: inline;">i</sub> &lt; n</li>
</ul>
<p><strong>解法一</strong></p>
<p>208周赛T4，有点白给，想好怎么处理就很简单（好不容易T4这么简单，被T2，T3给干懵了）</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maximumRequests</span><span class="params">(<span class="keyword">int</span> n, <span class="keyword">int</span>[][] requests)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span>[] nums = <span class="keyword">new</span> <span class="keyword">int</span>[n+<span class="number">1</span>];</span><br><span class="line">        dfs(nums, <span class="number">0</span>, requests, <span class="number">0</span>);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> idx, <span class="keyword">int</span>[][] requests, <span class="keyword">int</span> count)</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (check(nums)) &#123;</span><br><span class="line">            res = Math.max(res, count);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = idx; i &lt; requests.length; i++) &#123;</span><br><span class="line">            nums[requests[i][<span class="number">0</span>]]--;</span><br><span class="line">            nums[requests[i][<span class="number">1</span>]]++;</span><br><span class="line">            dfs(nums, i+<span class="number">1</span>, requests, count+<span class="number">1</span>);</span><br><span class="line">            nums[requests[i][<span class="number">0</span>]]++;</span><br><span class="line">            nums[requests[i][<span class="number">1</span>]]--;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">check</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; nums.length; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (nums[i] != <span class="number">0</span>) &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="二维平面上的回溯"><a href="#二维平面上的回溯" class="headerlink" title="二维平面上的回溯"></a><em>二维平面上的回溯</em></h2><h2 id="79-单词搜索"><a href="#79-单词搜索" class="headerlink" title="79. 单词搜索"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/word-search/" >79. 单词搜索<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二维网格和一个单词，找出该单词是否存在于网格中。</p>
<p>单词必须按照字母顺序，通过相邻的单元格内的字母构成，其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">board =</span><br><span class="line">[</span><br><span class="line">  [<span class="string">&#x27;A&#x27;</span>,<span class="string">&#x27;B&#x27;</span>,<span class="string">&#x27;C&#x27;</span>,<span class="string">&#x27;E&#x27;</span>],</span><br><span class="line">  [<span class="string">&#x27;S&#x27;</span>,<span class="string">&#x27;F&#x27;</span>,<span class="string">&#x27;C&#x27;</span>,<span class="string">&#x27;S&#x27;</span>],</span><br><span class="line">  [<span class="string">&#x27;A&#x27;</span>,<span class="string">&#x27;D&#x27;</span>,<span class="string">&#x27;E&#x27;</span>,<span class="string">&#x27;E&#x27;</span>]</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line">给定 word = <span class="string">&quot;ABCCED&quot;</span>, 返回 <span class="keyword">true</span>.</span><br><span class="line">给定 word = <span class="string">&quot;SEE&quot;</span>, 返回 <span class="keyword">true</span>.</span><br><span class="line">给定 word = <span class="string">&quot;ABCB&quot;</span>, 返回 <span class="keyword">false</span>.</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>这题其实并不难，但是我一开始就钻到死胡里去了，我直接拿起来就想的是暴力dfs从（0，0）开始遍历每种情况，直到找到一个相等的。。。我真是个hapi</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">    board =</span></span><br><span class="line"><span class="comment">    [</span></span><br><span class="line"><span class="comment">      [&#x27;A&#x27;,&#x27;B&#x27;,&#x27;C&#x27;,&#x27;E&#x27;],</span></span><br><span class="line"><span class="comment">      [&#x27;S&#x27;,&#x27;F&#x27;,&#x27;C&#x27;,&#x27;S&#x27;],</span></span><br><span class="line"><span class="comment">      [&#x27;A&#x27;,&#x27;D&#x27;,&#x27;E&#x27;,&#x27;E&#x27;]</span></span><br><span class="line"><span class="comment">    ]</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//方向: 右,下,左,上</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">int</span>[][] direction=&#123;&#123;<span class="number">0</span>,<span class="number">1</span>&#125;,&#123;<span class="number">1</span>,<span class="number">0</span>&#125;,&#123;<span class="number">0</span>,-<span class="number">1</span>&#125;,&#123;-<span class="number">1</span>,<span class="number">0</span>&#125;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">exist</span><span class="params">(<span class="keyword">char</span>[][] board, String word)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (board==<span class="keyword">null</span> || word==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">char</span>[] words=word.toCharArray();</span><br><span class="line">    <span class="keyword">boolean</span>[][] visit=<span class="keyword">new</span> <span class="keyword">boolean</span>[board.length][board[<span class="number">0</span>].length];</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;board.length;i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;board[<span class="number">0</span>].length;j++) &#123;</span><br><span class="line">            <span class="comment">//遍历board每个元素,以为个元素为起点都试一下</span></span><br><span class="line">            <span class="keyword">if</span>(dfs(board,words,<span class="number">0</span>,i,j,visit))&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">dfs</span><span class="params">(<span class="keyword">char</span>[][] board, <span class="keyword">char</span>[] word,<span class="keyword">int</span> index,<span class="keyword">int</span> x,<span class="keyword">int</span> y,<span class="keyword">boolean</span>[][] visit)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//遍历到word的最后一个字符了,直接比较就可以得出结果</span></span><br><span class="line">    <span class="keyword">if</span> (index == word.length-<span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> word[index] == board[x][y];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">     这样写如果board只有一个元素就会错了,后面的isValid会直接false,但是有可能word就是这个board</span></span><br><span class="line"><span class="comment">     if (index == word.length) &#123;</span></span><br><span class="line"><span class="comment">            return true;</span></span><br><span class="line"><span class="comment">     &#125;*/</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">//当元素相等的时候才有继续的必要</span></span><br><span class="line">    <span class="keyword">if</span> (board[x][y]==word[index]) &#123;</span><br><span class="line">        visit[x][y]=<span class="keyword">true</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;direction.length;i++) &#123;</span><br><span class="line">            <span class="keyword">int</span> nx=x+direction[i][<span class="number">0</span>];</span><br><span class="line">            <span class="keyword">int</span> ny=y+direction[i][<span class="number">1</span>];</span><br><span class="line">            <span class="comment">//保证合法性</span></span><br><span class="line">            <span class="keyword">if</span> (isValid(board,nx,ny)&amp;&amp;!visit[nx][ny]&amp;&amp;dfs(board,word,index+<span class="number">1</span>,nx,ny,visit)) &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        visit[x][y]=<span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isValid</span><span class="params">(<span class="keyword">char</span>[][] cs,<span class="keyword">int</span> x,<span class="keyword">int</span> y)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> x&gt;=<span class="number">0</span> &amp;&amp; x&lt;cs.length &amp;&amp; y &gt;=<span class="number">0</span> &amp;&amp; y&lt; cs[<span class="number">0</span>].length;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="200-岛屿数量"><a href="#200-岛屿数量" class="headerlink" title="200. 岛屿数量"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/number-of-islands/" >200. 岛屿数量<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个由 ‘1’（陆地）和 ‘0’（水）组成的的二维网格，计算岛屿的数量。一个岛被水包围，并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line"><span class="number">11110</span></span><br><span class="line"><span class="number">11010</span></span><br><span class="line"><span class="number">11000</span></span><br><span class="line"><span class="number">00000</span></span><br><span class="line"></span><br><span class="line">输出: <span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line"><span class="number">11000</span></span><br><span class="line"><span class="number">11000</span></span><br><span class="line"><span class="number">00100</span></span><br><span class="line"><span class="number">00011</span></span><br><span class="line"></span><br><span class="line">输出: <span class="number">3</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>和上面一题类似，很惭愧，一开始也没写出来，写了个大概，细节没有捋清楚</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//方向: 右,下,左,上</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">int</span>[][] direction=&#123;&#123;<span class="number">0</span>,<span class="number">1</span>&#125;,&#123;<span class="number">1</span>,<span class="number">0</span>&#125;,&#123;<span class="number">0</span>,-<span class="number">1</span>&#125;,&#123;-<span class="number">1</span>,<span class="number">0</span>&#125;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">numIslands</span><span class="params">(<span class="keyword">char</span>[][] grid)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (grid==<span class="keyword">null</span>||grid.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">boolean</span>[][] visit=<span class="keyword">new</span> <span class="keyword">boolean</span>[grid.length][grid[<span class="number">0</span>].length];</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;grid.length;i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;grid[<span class="number">0</span>].length;j++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (grid[i][j]==<span class="string">&#x27;1&#x27;</span>&amp;&amp;!visit[i][j]) &#123;</span><br><span class="line">                dfs(grid,i,j,visit);</span><br><span class="line">                res++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">char</span>[][] grid,<span class="keyword">int</span> x,<span class="keyword">int</span> y,<span class="keyword">boolean</span>[][] visit)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//其实整个dfs做的就是对visit[x][y]标记,标记为true代表访问过</span></span><br><span class="line">    visit[x][y]=<span class="keyword">true</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;direction.length;i++) &#123;</span><br><span class="line">        <span class="keyword">int</span> nx=x+direction[i][<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">int</span> ny=y+direction[i][<span class="number">1</span>];</span><br><span class="line">        <span class="keyword">if</span> (isValid(grid,nx,ny) &amp;&amp; !visit[nx][ny] &amp;&amp; grid[nx][ny]==<span class="string">&#x27;1&#x27;</span>) &#123;</span><br><span class="line">            dfs(grid,nx,ny,visit);</span><br><span class="line">            <span class="comment">//无需回溯visit状态</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isValid</span><span class="params">(<span class="keyword">final</span> <span class="keyword">char</span>[][] grid,<span class="keyword">int</span> x,<span class="keyword">int</span> y)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> x&gt;=<span class="number">0</span> &amp;&amp; x&lt;grid.length &amp;&amp; y&gt;=<span class="number">0</span> &amp;&amp; y&lt;grid[<span class="number">0</span>].length;</span><br><span class="line">&#125; </span><br></pre></td></tr></table></figure>
<h2 id="130-被围绕的区域"><a href="#130-被围绕的区域" class="headerlink" title="130. 被围绕的区域"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/surrounded-regions/" >130. 被围绕的区域<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二维的矩阵，包含 <code>&#39;X&#39;</code> 和 <code>&#39;O&#39;</code>（<strong>字母 O</strong>）。</p>
<p>找到所有被 ‘X’ 围绕的区域，并将这些区域里所有的 <code>&#39;O&#39;</code> 用 <code>&#39;X&#39;</code> 填充。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">X X X X</span><br><span class="line">X O O X</span><br><span class="line">X X O X</span><br><span class="line">X O X X</span><br></pre></td></tr></table></figure>


<p>运行你的函数后，矩阵变为：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">X X X X</span><br><span class="line">X X X X</span><br><span class="line">X X X X</span><br><span class="line">X O X X</span><br></pre></td></tr></table></figure>

<p><strong>解释:</strong></p>
<p>被围绕的区间不会存在于边界上，换句话说，任何边界上的 ‘O’ 都不会被填充为 ‘X’。 任何不在边界上，或不与边界上的 ‘O’ 相连的 ‘O’ 最终都会被填充为 ‘X’。如果两个元素在水平或垂直方向相邻，则称它们是“相连”的</p>
<p><strong>解法一</strong></p>
<p>这题在很久以前（看了提交记录是一年前的）开始学dfs的时候，在leetcode搜索到了这一题，当时也做出来了，只不过效率感人，放上来看看是个啥玩意</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 定义4个方向（顺时针 右...）</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">int</span>[][] direction = &#123; &#123; <span class="number">1</span>, <span class="number">0</span> &#125;, &#123; <span class="number">0</span>, <span class="number">1</span> &#125;, &#123; -<span class="number">1</span>, <span class="number">0</span> &#125;, &#123; <span class="number">0</span>, -<span class="number">1</span> &#125; &#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">int</span>[][] mark = <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">solve</span><span class="params">(<span class="keyword">char</span>[][] board)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(board.length==<span class="number">0</span>) &#123; <span class="keyword">return</span>; &#125;</span><br><span class="line">    <span class="comment">// 根据传进来的board给mark初始化</span></span><br><span class="line">    mark = <span class="keyword">new</span> <span class="keyword">int</span>[board.length][board[<span class="number">0</span>].length];</span><br><span class="line">    <span class="comment">// 遍历边缘找出边缘的 O 的坐标</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; board.length; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (board[i][<span class="number">0</span>] == <span class="string">&#x27;O&#x27;</span>) &#123;</span><br><span class="line">            dfs(<span class="number">0</span>, i, board);</span><br><span class="line">            <span class="comment">//执行完之后再赋值当前位置的O 避免在边缘角落的问题</span></span><br><span class="line">            mark[i][<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (board[i][board[<span class="number">0</span>].length - <span class="number">1</span>] == <span class="string">&#x27;O&#x27;</span>) &#123;</span><br><span class="line">            dfs(board[<span class="number">0</span>].length, i, board);</span><br><span class="line">            mark[i][board[<span class="number">0</span>].length - <span class="number">1</span>] = <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 上边缘</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; board[<span class="number">0</span>].length; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (board[<span class="number">0</span>][i] == <span class="string">&#x27;O&#x27;</span>) &#123;</span><br><span class="line">            dfs(i, <span class="number">0</span>, board);</span><br><span class="line">            mark[<span class="number">0</span>][i] = <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 下边缘</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; board[<span class="number">0</span>].length; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (board[board.length - <span class="number">1</span>][i] == <span class="string">&#x27;O&#x27;</span>) &#123;</span><br><span class="line">            dfs(i, board.length - <span class="number">1</span>, board);</span><br><span class="line">            mark[board.length - <span class="number">1</span>][i] = <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; board.length; i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; board[<span class="number">0</span>].length; j++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (board[i][j] == <span class="string">&#x27;O&#x27;</span> &amp;&amp; mark[i][j] == <span class="number">0</span>) &#123;</span><br><span class="line">                board[i][j] = <span class="string">&#x27;X&#x27;</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 实现函数</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span> x, <span class="keyword">int</span> y, <span class="keyword">char</span>[][] board)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> tx, ty;</span><br><span class="line">    <span class="comment">// 首先判断边缘上有没有 O 有的话将与他联通的 O 都加上标记</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt;= <span class="number">3</span>; i++) &#123;</span><br><span class="line">        <span class="comment">// x=x+direction[i][0]; 这样写每个点向4个方向扩展如果这样写 点的走向就有问题了</span></span><br><span class="line">        tx = x + direction[i][<span class="number">0</span>];</span><br><span class="line">        ty = y + direction[i][<span class="number">1</span>];</span><br><span class="line">        <span class="comment">// System.out.println(tx+&quot; &quot;+ty);</span></span><br><span class="line">        <span class="keyword">if</span> (tx &lt; board[<span class="number">0</span>].length &amp;&amp; tx &gt;= <span class="number">0</span> &amp;&amp; ty &lt; board.length &amp;&amp; ty &gt;= <span class="number">0</span> &amp;&amp; board[ty][tx] == <span class="string">&#x27;O&#x27;</span></span><br><span class="line">            &amp;&amp; mark[ty][tx] == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="comment">// 代表走过了</span></span><br><span class="line">            mark[ty][tx] = <span class="number">1</span>;</span><br><span class="line">            <span class="comment">// 这里没有处理好，我的dfs函数的参数是坐标但是对应到mark里面和board里面就不是坐标了就颠倒了</span></span><br><span class="line">            <span class="comment">// 比如按照坐标来 2 , 1 ----&gt;对应到数组里面就是 1 ，2</span></span><br><span class="line">            dfs(tx, ty, board);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>21ms，8% 乍一看好像没啥问题，但是为啥这么慢呢？看看今天下午重新做的解</p>
<p><strong>解法二</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//方向: 右,下,左,上</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">int</span>[][] direction=&#123;&#123;<span class="number">0</span>,<span class="number">1</span>&#125;,&#123;<span class="number">1</span>,<span class="number">0</span>&#125;,&#123;<span class="number">0</span>,-<span class="number">1</span>&#125;,&#123;-<span class="number">1</span>,<span class="number">0</span>&#125;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">solve</span><span class="params">(<span class="keyword">char</span>[][] board)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (board==<span class="keyword">null</span> || board.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">boolean</span>[][] visit=<span class="keyword">new</span> <span class="keyword">boolean</span>[board.length][board[<span class="number">0</span>].length];</span><br><span class="line">    <span class="keyword">int</span> lx=<span class="number">0</span>,ly=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//遍历4条边的&#x27;O&#x27;,将与相连的&#x27;O&#x27;都标记为true</span></span><br><span class="line">    <span class="keyword">while</span>(lx&lt;board.length) &#123; </span><br><span class="line">        <span class="keyword">if</span> (board[lx][<span class="number">0</span>]==<span class="string">&#x27;O&#x27;</span>) &#123; <span class="comment">//左</span></span><br><span class="line">            dfs(board,lx,<span class="number">0</span>,visit);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (board[lx][board[<span class="number">0</span>].length-<span class="number">1</span>] == <span class="string">&#x27;O&#x27;</span>) &#123; <span class="comment">//右</span></span><br><span class="line">            dfs(board,lx,board[<span class="number">0</span>].length-<span class="number">1</span>,visit);</span><br><span class="line">        &#125;</span><br><span class="line">        lx++;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span>(ly&lt;board[<span class="number">0</span>].length) &#123; </span><br><span class="line">        <span class="keyword">if</span> (board[<span class="number">0</span>][ly]==<span class="string">&#x27;O&#x27;</span>) &#123; <span class="comment">//上</span></span><br><span class="line">            dfs(board,<span class="number">0</span>,ly,visit);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (board[board.length-<span class="number">1</span>][ly] == <span class="string">&#x27;O&#x27;</span>) &#123; <span class="comment">//下</span></span><br><span class="line">            dfs(board,board.length-<span class="number">1</span>,ly,visit);   </span><br><span class="line">        &#125;</span><br><span class="line">        ly++;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//遍历将所有visit=false的O变为X</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;board.length;i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;board[<span class="number">0</span>].length;j++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (board[i][j]==<span class="string">&#x27;O&#x27;</span> &amp;&amp; !visit[i][j]) &#123;</span><br><span class="line">                board[i][j]=<span class="string">&#x27;X&#x27;</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">char</span>[][] board,<span class="keyword">int</span> x,<span class="keyword">int</span> y,<span class="keyword">boolean</span>[][] visit)</span> </span>&#123;</span><br><span class="line">    visit[x][y]=<span class="keyword">true</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;direction.length;i++) &#123;</span><br><span class="line">        <span class="keyword">int</span> nx=x+direction[i][<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">int</span> ny=y+direction[i][<span class="number">1</span>];</span><br><span class="line">        <span class="keyword">if</span> (isValid(board,nx,ny) &amp;&amp; board[nx][ny]==<span class="string">&#x27;O&#x27;</span> &amp;&amp; !visit[nx][ny]) &#123;</span><br><span class="line">            dfs(board,nx,ny,visit);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//是否合法</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isValid</span><span class="params">(<span class="keyword">final</span> <span class="keyword">char</span>[][] grid,<span class="keyword">int</span> x,<span class="keyword">int</span> y)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> x&gt;=<span class="number">0</span> &amp;&amp; x&lt;grid.length &amp;&amp; y&gt;=<span class="number">0</span> &amp;&amp; y&lt;grid[<span class="number">0</span>].length;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>2ms，比较明显的区别就是dfs给visit数组赋值的时机不同，一个是在循环里面，一个是在函数开头，也就是说第一种解法并不会立即给边缘的<code>&#39;O&#39;</code> 标记，这样导致的问题就是它后续的节点仍然会搜索到这个边缘的 <code>&#39;O&#39;</code> 这样就会造成重复的计算，所以说，一定要捋清楚这个过程，不能乱写</p>
<h2 id="417-太平洋大西洋水流问题"><a href="#417-太平洋大西洋水流问题" class="headerlink" title="417. 太平洋大西洋水流问题"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/pacific-atlantic-water-flow/" >417. 太平洋大西洋水流问题<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个 <code>m x n</code> 的非负整数矩阵来表示一片大陆上各个单元格的高度。“太平洋”处于大陆的左边界和上边界，而“大西洋”处于大陆的右边界和下边界。</p>
<p>规定水流只能按照上、下、左、右四个方向流动，且只能从高到低或者在同等高度上流动。</p>
<p>请找出那些水流既可以流动到“太平洋”，又能流动到“大西洋”的陆地单元的坐标</p>
<p><strong>提示：</strong></p>
<ol>
<li><p>输出坐标的顺序不重要</p>
</li>
<li><p>m 和 n 都小于150</p>
</li>
</ol>
<p><strong>示例：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">给定下面的 5x5 矩阵:</span><br><span class="line"></span><br><span class="line">  太平洋 ~   ~   ~   ~   ~ </span><br><span class="line">       ~  <span class="number">1</span>   <span class="number">2</span>   <span class="number">2</span>   <span class="number">3</span>  (<span class="number">5</span>) *</span><br><span class="line">       ~  <span class="number">3</span>   <span class="number">2</span>   <span class="number">3</span>  (<span class="number">4</span>) (<span class="number">4</span>) *</span><br><span class="line">       ~  <span class="number">2</span>   <span class="number">4</span>  (<span class="number">5</span>)  <span class="number">3</span>   <span class="number">1</span>  *</span><br><span class="line">       ~ (<span class="number">6</span>) (<span class="number">7</span>)  <span class="number">1</span>   <span class="number">4</span>   <span class="number">5</span>  *</span><br><span class="line">       ~ (<span class="number">5</span>)  <span class="number">1</span>   <span class="number">1</span>   <span class="number">2</span>   <span class="number">4</span>  *</span><br><span class="line">          *   *   *   *   * 大西洋</span><br><span class="line"></span><br><span class="line">返回:</span><br><span class="line"></span><br><span class="line">[[<span class="number">0</span>, <span class="number">4</span>], [<span class="number">1</span>, <span class="number">3</span>], [<span class="number">1</span>, <span class="number">4</span>], [<span class="number">2</span>, <span class="number">2</span>], [<span class="number">3</span>, <span class="number">0</span>], [<span class="number">3</span>, <span class="number">1</span>], [<span class="number">4</span>, <span class="number">0</span>]] (上图中带括号的单元).</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>其实和上面也是如出一辙，只不过最开始没想到两个visit数组来做</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//方向键</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">int</span>[][] direction=&#123;&#123;<span class="number">0</span>,<span class="number">1</span>&#125;,&#123;<span class="number">1</span>,<span class="number">0</span>&#125;,&#123;<span class="number">0</span>,-<span class="number">1</span>&#125;,&#123;-<span class="number">1</span>,<span class="number">0</span>&#125;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; pacificAtlantic(<span class="keyword">int</span>[][] matrix) &#123;</span><br><span class="line">    List&lt;List&lt;Integer&gt;&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="comment">//leetcode老是喜欢搞些幺蛾子</span></span><br><span class="line">    <span class="keyword">if</span> (matrix==<span class="keyword">null</span> || matrix.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> m=matrix.length;</span><br><span class="line">    <span class="keyword">int</span> n=matrix[<span class="number">0</span>].length;</span><br><span class="line">    <span class="comment">//太平洋</span></span><br><span class="line">    <span class="keyword">boolean</span>[][] pacific=<span class="keyword">new</span> <span class="keyword">boolean</span>[m][n];</span><br><span class="line">    <span class="comment">//大西洋</span></span><br><span class="line">    <span class="keyword">boolean</span>[][] atlantic=<span class="keyword">new</span> <span class="keyword">boolean</span>[m][n];</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;m;i++) &#123;</span><br><span class="line">        dfs(matrix,i,<span class="number">0</span>,pacific);</span><br><span class="line">        dfs(matrix,i,n-<span class="number">1</span>,atlantic);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;n;i++) &#123;</span><br><span class="line">        dfs(matrix,<span class="number">0</span>,i,pacific);</span><br><span class="line">        dfs(matrix,m-<span class="number">1</span>,i,atlantic);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;m;i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;n;j++) &#123;</span><br><span class="line">            <span class="comment">//同时为true的就是解</span></span><br><span class="line">            <span class="keyword">if</span> (pacific[i][j] &amp;&amp; atlantic[i][j]) &#123;</span><br><span class="line">                res.add(Arrays.asList(i,j));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span>[][] matrix,<span class="keyword">int</span> x,<span class="keyword">int</span> y,<span class="keyword">boolean</span>[][] visit)</span> </span>&#123;</span><br><span class="line">    visit[x][y]=<span class="keyword">true</span>;</span><br><span class="line">    <span class="comment">//向4个方向floodfill</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;direction.length;i++) &#123;</span><br><span class="line">        <span class="keyword">int</span> nx=x+direction[i][<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">int</span> ny=y+direction[i][<span class="number">1</span>];</span><br><span class="line">        <span class="keyword">if</span> (isValid(matrix,nx,ny) &amp;&amp; matrix[nx][ny]&gt;= matrix[x][y] &amp;&amp; !visit[nx][ny]) &#123;</span><br><span class="line">            dfs(matrix,nx,ny,visit);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isValid</span><span class="params">(<span class="keyword">final</span> <span class="keyword">int</span>[][] matrix,<span class="keyword">int</span> x,<span class="keyword">int</span> y)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> x&gt;=<span class="number">0</span> &amp;&amp; x&lt;matrix.length &amp;&amp; y&gt;=<span class="number">0</span> &amp;&amp; y&lt;matrix[<span class="number">0</span>].length;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>6ms，96%，还是比较ok的</p>
<h2 id="51-N皇后"><a href="#51-N皇后" class="headerlink" title="51. N皇后"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/n-queens/" >51. N皇后<i class="fas fa-external-link-alt"></i></a></h2><p><em>n</em> 皇后问题研究的是如何将 <em>n</em> 个皇后放置在 <em>n</em>×<em>n</em> 的棋盘上，并且使皇后彼此之间不能相互攻击</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/blog/20191011/ac4lTcAFesSc.png?imageslim"
                      alt="mark"
                ></p>
<p>上图为 8 皇后问题的一种解法。</p>
<p>给定一个整数 n，返回所有不同的 n 皇后问题的解决方案。</p>
<p>每一种解法包含一个明确的 n 皇后问题的棋子放置方案，该方案中 ‘Q’ 和 ‘ . ‘ 分别代表了皇后和空位。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="number">4</span></span><br><span class="line">输出: [</span><br><span class="line"> [<span class="string">&quot;.Q..&quot;</span>,  <span class="comment">// 解法 1</span></span><br><span class="line">  <span class="string">&quot;...Q&quot;</span>,</span><br><span class="line">  <span class="string">&quot;Q...&quot;</span>,</span><br><span class="line">  <span class="string">&quot;..Q.&quot;</span>],</span><br><span class="line"></span><br><span class="line"> [<span class="string">&quot;..Q.&quot;</span>,  <span class="comment">// 解法 2</span></span><br><span class="line">  <span class="string">&quot;Q...&quot;</span>,</span><br><span class="line">  <span class="string">&quot;...Q&quot;</span>,</span><br><span class="line">  <span class="string">&quot;.Q..&quot;</span>]</span><br><span class="line">]</span><br><span class="line">解释: <span class="number">4</span> 皇后问题存在两个不同的解法</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>Hard题，N皇后问题可以说是很经典的问题了，之前有看过，但是都是一脸懵逼，无从下手，这一次看了下提示还是自己给做出来了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> List&lt;List&lt;String&gt;&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span>[] col;</span><br><span class="line"><span class="comment">//private boolean[] row;</span></span><br><span class="line"><span class="comment">//两条对角线</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span>[] dia1;</span><br><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span>[] dia2;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> List&lt;List&lt;String&gt;&gt; solveNQueens(<span class="keyword">int</span> n) &#123;</span><br><span class="line">    <span class="keyword">if</span> (n&lt;=<span class="number">0</span>) <span class="keyword">return</span> res;</span><br><span class="line">    col=<span class="keyword">new</span> <span class="keyword">boolean</span>[n];</span><br><span class="line">    <span class="comment">//row=new boolean[n];</span></span><br><span class="line">    dia1=<span class="keyword">new</span> <span class="keyword">boolean</span>[<span class="number">2</span>*n-<span class="number">1</span>];</span><br><span class="line">    dia2=<span class="keyword">new</span> <span class="keyword">boolean</span>[<span class="number">2</span>*n-<span class="number">1</span>];</span><br><span class="line">    dfs(n,<span class="number">0</span>,<span class="keyword">new</span> ArrayList());</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//dfs</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span> n,<span class="keyword">int</span> index,List&lt;Integer&gt; lis)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (index==n) &#123;</span><br><span class="line">        res.add(generateRes(lis));</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//检测第index行第i列</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;n;i++) &#123;</span><br><span class="line">        <span class="comment">//注意对角线的下标</span></span><br><span class="line">        <span class="keyword">if</span> (!col[i] &amp;&amp; !dia1[index-i+n-<span class="number">1</span>] &amp;&amp; !dia2[i+index]) &#123;</span><br><span class="line">            col[i]=<span class="keyword">true</span>;</span><br><span class="line">            dia1[index-i+n-<span class="number">1</span>]=<span class="keyword">true</span>;</span><br><span class="line">            dia2[index+i]=<span class="keyword">true</span>;</span><br><span class="line">            <span class="comment">//尝试添加</span></span><br><span class="line">            lis.add(i);</span><br><span class="line">            dfs(n,index+<span class="number">1</span>,lis);</span><br><span class="line">            <span class="comment">//回溯</span></span><br><span class="line">            lis.remove(lis.size()-<span class="number">1</span>);</span><br><span class="line">            col[i]=<span class="keyword">false</span>;</span><br><span class="line">            dia1[index-i+n-<span class="number">1</span>]=<span class="keyword">false</span>;</span><br><span class="line">            dia2[index+i]=<span class="keyword">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//根据lis生成解</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;String&gt; <span class="title">generateRes</span><span class="params">(List&lt;Integer&gt; lis)</span></span>&#123;</span><br><span class="line">    List&lt;String&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;lis.size();i++) &#123;</span><br><span class="line">        <span class="keyword">int</span> index = lis.get(i);</span><br><span class="line">        StringBuilder sb=<span class="keyword">new</span> StringBuilder();</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;lis.size();j++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (j!=index)&#123;</span><br><span class="line">                sb.append(<span class="string">&quot;.&quot;</span>);</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                sb.append(<span class="string">&quot;Q&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        res.add(sb.toString());</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>核心思路就是：一行行遍历，然后dfs尝试在每个位置放置皇后，我觉得主要的难点在于如何判断各个列，对角线是否已经有皇后，这一点需要细致的观察，有一条对角线的横纵坐标之和为常数，另一条横纵坐标之差是个常数，借此便可以唯一确定一条对角线</p>
<h2 id="52-N皇后-II"><a href="#52-N皇后-II" class="headerlink" title="52. N皇后 II"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/n-queens-ii/" >52. N皇后 II<i class="fas fa-external-link-alt"></i></a></h2><p>和上面一题不同的地方是这题只需要求解的个数，感觉这题才应该是<code>Ⅰ</code>，不用求所有的解，貌似更加简单了？</p>
<p><strong>解法一</strong></p>
<p>直接套用上面的代码，没啥好说的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">totalNQueens</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">    res=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">if</span> (n&lt;=<span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    col=<span class="keyword">new</span> <span class="keyword">boolean</span>[n];</span><br><span class="line">    <span class="comment">//row=new boolean[n];</span></span><br><span class="line">    dia1=<span class="keyword">new</span> <span class="keyword">boolean</span>[<span class="number">2</span>*n-<span class="number">1</span>];</span><br><span class="line">    dia2=<span class="keyword">new</span> <span class="keyword">boolean</span>[<span class="number">2</span>*n-<span class="number">1</span>];</span><br><span class="line">    dfs(n,<span class="number">0</span>,<span class="keyword">new</span> ArrayList());</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span>[] col;</span><br><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span>[] dia1;</span><br><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span>[] dia2;</span><br><span class="line"></span><br><span class="line"><span class="comment">//dfs</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span> n,<span class="keyword">int</span> index,List&lt;Integer&gt; lis)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (index==n) &#123;</span><br><span class="line">        res++;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//检测第index行第i列</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;n;i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!col[i] &amp;&amp; !dia1[index-i+n-<span class="number">1</span>] &amp;&amp; !dia2[i+index]) &#123;</span><br><span class="line">            col[i]=<span class="keyword">true</span>;</span><br><span class="line">            dia1[index-i+n-<span class="number">1</span>]=<span class="keyword">true</span>;</span><br><span class="line">            dia2[index+i]=<span class="keyword">true</span>;</span><br><span class="line">            <span class="comment">//不用添加到lis中</span></span><br><span class="line">            dfs(n,index+<span class="number">1</span>,lis);</span><br><span class="line">            <span class="comment">//回溯</span></span><br><span class="line">            col[i]=<span class="keyword">false</span>;</span><br><span class="line">            dia1[index-i+n-<span class="number">1</span>]=<span class="keyword">false</span>;</span><br><span class="line">            dia2[index+i]=<span class="keyword">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>虽然提交了也是1ms，主要是这两题case都比较少，最大的case好像只到11，所以差距不是很明显，我这样做肯定不是这题的最优解，这题的最优解是利用<code>位图（bitmap）</code>作位运算，反正我不可能写出来就是了😂 <a class="link"   target="_blank" rel="noopener" href="http://www.ic-net.or.jp/home/takaken/e/queen/" >参考<i class="fas fa-external-link-alt"></i></a></p>
<h2 id="37-解数独"><a href="#37-解数独" class="headerlink" title="37. 解数独"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/sudoku-solver/" >37. 解数独<i class="fas fa-external-link-alt"></i></a></h2><p>编写一个程序，通过已填充的空格来解决数独问题。</p>
<p>一个数独的解法需遵循如下规则：</p>
<p>数字 <code>1-9</code> 在每一行只能出现一次。<br>数字 <code>1-9</code> 在每一列只能出现一次。<br>数字 1-9 在每一个以粗实线分隔的 <code>3x3</code> 宫内只能出现一次。<br>空白格用 <code>&#39;.&#39;</code> 表示。</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/blog/20191012/jvSukv6RnXFL.png?imageslim"
                      alt="mark"
                ></p>
<p>一个数独</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/blog/20191012/XgTokVUgo5Yy.png?imageslim"
                      alt="mark"
                ></p>
<p>答案被标成红色。</p>
<p><strong>Note:</strong></p>
<ul>
<li>给定的数独序列只包含数字 <code>1-9</code> 和字符 <code>&#39;.&#39;</code> </li>
<li>你可以假设给定的数独只有唯一解。</li>
<li>给定数独永远是 <code>9x9</code> 形式的。</li>
</ul>
<p><strong>解法一</strong></p>
<p>嗯，又是一道hard题，自己摸了半天没做出来，看了评论区做出来的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//三个约束规则</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span>[][] col=<span class="keyword">new</span> <span class="keyword">boolean</span>[<span class="number">9</span>][<span class="number">9</span>];</span><br><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span>[][] row=<span class="keyword">new</span> <span class="keyword">boolean</span>[<span class="number">9</span>][<span class="number">9</span>];</span><br><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span>[][] block=<span class="keyword">new</span> <span class="keyword">boolean</span>[<span class="number">9</span>][<span class="number">9</span>];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">solveSudoku</span><span class="params">(<span class="keyword">char</span>[][] board)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (board==<span class="keyword">null</span> || board.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;<span class="number">9</span>;i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;<span class="number">9</span>;j++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (board[i][j]!=<span class="string">&#x27;.&#x27;</span>) &#123;</span><br><span class="line">                col[i][board[i][j]-<span class="number">48</span>-<span class="number">1</span>]=<span class="keyword">true</span>;</span><br><span class="line">                row[j][board[i][j]-<span class="number">48</span>-<span class="number">1</span>]=<span class="keyword">true</span>;</span><br><span class="line">                <span class="comment">//块号为 i/3*3+j/3</span></span><br><span class="line">                block[i/<span class="number">3</span>*<span class="number">3</span>+j/<span class="number">3</span>][board[i][j]-<span class="number">48</span>-<span class="number">1</span>]=<span class="keyword">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(board,<span class="number">0</span>,<span class="number">0</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//private  static char[][] res=new char[9][9];</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">dfs</span><span class="params">(<span class="keyword">char</span>[][] board,<span class="keyword">int</span> i,<span class="keyword">int</span> j)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//从,i,j位置向后寻找&#x27;.&#x27;, i&gt;=9说明全部填充完了</span></span><br><span class="line">    <span class="keyword">while</span>(board[i][j]!=<span class="string">&#x27;.&#x27;</span>) &#123;</span><br><span class="line">        j++;</span><br><span class="line">        <span class="keyword">if</span> (j==<span class="number">9</span>) &#123;</span><br><span class="line">            i++;</span><br><span class="line">            j=<span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//over</span></span><br><span class="line">        <span class="keyword">if</span> (i==<span class="number">9</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//System.out.println(i+&quot;,&quot;+j);</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> val=<span class="number">0</span>;val&lt;<span class="number">9</span>;val++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!col[i][val] &amp;&amp; !row[j][val] &amp;&amp; !block[i/<span class="number">3</span>*<span class="number">3</span>+j/<span class="number">3</span>][val]) &#123;</span><br><span class="line">            col[i][val]=<span class="keyword">true</span>;</span><br><span class="line">            row[j][val]=<span class="keyword">true</span>;</span><br><span class="line">            block[i/<span class="number">3</span>*<span class="number">3</span>+j/<span class="number">3</span>][val]=<span class="keyword">true</span>;</span><br><span class="line">            <span class="comment">//尝试填充为 val+1</span></span><br><span class="line">            board[i][j]=(<span class="keyword">char</span>)(val+<span class="number">1</span>+<span class="number">48</span>);</span><br><span class="line">            <span class="comment">//尝试后面的&#x27;.&#x27;,这里传进去还是i,j</span></span><br><span class="line">            <span class="comment">//大脑模拟下其实这个dfs过程也挺简单</span></span><br><span class="line">            <span class="keyword">if</span>(dfs(board,i,j))&#123;<span class="comment">//这里会尝试所有解，失败后回溯</span></span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="comment">//回溯</span></span><br><span class="line">                board[i][j]=<span class="string">&#x27;.&#x27;</span>;</span><br><span class="line">                col[i][val]=<span class="keyword">false</span>;</span><br><span class="line">                row[j][val]=<span class="keyword">false</span>;</span><br><span class="line">                block[i/<span class="number">3</span>*<span class="number">3</span>+j/<span class="number">3</span>][val]=<span class="keyword">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>比上面的N皇后要更复杂，同样也是带有约束的dfs回溯，我一开始写的方法主要是思路都错了，我想的和上面n皇后一样，一层一层的搜索最后n==9就结束，但是没考虑到一层其实不只有一个<code>空位</code>，同时还要注意回溯的时机，并不是dfs之后就回溯，用大脑模拟下这个递归其实就明白了，我觉得核心还是<code>找&#39;.&#39;那一步</code>，这一步确实没想到</p>
<blockquote>
<p>这题有一个简单版，<a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/valid-sudoku/" >36. 有效的数独<i class="fas fa-external-link-alt"></i></a> 挺简单的，懒得做了</p>
</blockquote>
<h2 id="529-扫雷游戏"><a href="#529-扫雷游戏" class="headerlink" title="529. 扫雷游戏"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/minesweeper/" >529. 扫雷游戏<i class="fas fa-external-link-alt"></i></a></h2><p>让我们一起来玩扫雷游戏！</p>
<p>给定一个代表游戏板的二维字符矩阵。 ‘M’ 代表一个未挖出的地雷，’E’ 代表一个未挖出的空方块，’B’ 代表没有相邻（上，下，左，右，和所有4个对角线）地雷的已挖出的空白方块，数字（’1’ 到 ‘8’）表示有多少地雷与这块已挖出的方块相邻，’X’ 则表示一个已挖出的地雷。</p>
<p>现在给出在所有未挖出的方块中（’M’或者’E’）的下一个点击位置（行和列索引），根据以下规则，返回相应位置被点击后对应的面板：</p>
<ol>
<li>如果一个地雷（’M’）被挖出，游戏就结束了- 把它改为 ‘X’。</li>
<li>如果一个没有相邻地雷的空方块（’E’）被挖出，修改它为（’B’），并且所有和其相邻的方块都应该被递归地揭露。</li>
<li>如果一个至少与一个地雷相邻的空方块（’E’）被挖出，修改它为数字（’1’到’8’），表示相邻地雷的数量。</li>
<li>如果在此次点击中，若无更多方块可被揭露，则返回面板。</li>
</ol>
<p><strong>示例一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">Input: </span><br><span class="line"></span><br><span class="line">[[<span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;E&#x27;</span>],</span><br><span class="line"> [<span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;M&#x27;</span>, <span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;E&#x27;</span>],</span><br><span class="line"> [<span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;E&#x27;</span>],</span><br><span class="line"> [<span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;E&#x27;</span>]]</span><br><span class="line"></span><br><span class="line">Click : [<span class="number">3</span>,<span class="number">0</span>]</span><br><span class="line"></span><br><span class="line">Output: </span><br><span class="line"></span><br><span class="line">[[<span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;B&#x27;</span>],</span><br><span class="line"> [<span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;M&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;B&#x27;</span>],</span><br><span class="line"> [<span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;B&#x27;</span>],</span><br><span class="line"> [<span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;B&#x27;</span>]]</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p><strong>Explanation:</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2019/11/18/B26DWk8CrhPFtHI.png"
                      alt="扫雷"
                ></p>
<p><strong>示例二</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">Input: </span><br><span class="line"></span><br><span class="line">[[<span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;B&#x27;</span>],</span><br><span class="line"> [<span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;M&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;B&#x27;</span>],</span><br><span class="line"> [<span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;B&#x27;</span>],</span><br><span class="line"> [<span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;B&#x27;</span>]]</span><br><span class="line"></span><br><span class="line">Click : [<span class="number">1</span>,<span class="number">2</span>]</span><br><span class="line"></span><br><span class="line">Output: </span><br><span class="line"></span><br><span class="line">[[<span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;E&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;B&#x27;</span>],</span><br><span class="line"> [<span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;X&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;B&#x27;</span>],</span><br><span class="line"> [<span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;B&#x27;</span>],</span><br><span class="line"> [<span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;B&#x27;</span>]]</span><br></pre></td></tr></table></figure>

<p><strong>Explanation:</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s2.ax1x.com/2019/11/18/MyccWT.png"
                      alt="扫雷"
                ></p>
<p><strong>解法一</strong></p>
<p>标准的DFS，还是挺有意思的，向8个方向扩展，遇到周围有地雷的就计数并且停止，会玩扫雷就会做😉</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">int</span>[][] direction=&#123;&#123;<span class="number">0</span>,<span class="number">1</span>&#125;,&#123;<span class="number">1</span>,<span class="number">0</span>&#125;,&#123;-<span class="number">1</span>,<span class="number">1</span>&#125;,&#123;<span class="number">1</span>,-<span class="number">1</span>&#125;,&#123;-<span class="number">1</span>,<span class="number">0</span>&#125;,&#123;<span class="number">0</span>,-<span class="number">1</span>&#125;,&#123;-<span class="number">1</span>,-<span class="number">1</span>&#125;,&#123;<span class="number">1</span>,<span class="number">1</span>&#125;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">char</span>[][] updateBoard(<span class="keyword">char</span>[][] board, <span class="keyword">int</span>[] click) &#123;</span><br><span class="line">    <span class="keyword">int</span> x=click[<span class="number">0</span>];</span><br><span class="line">    <span class="keyword">int</span> y=click[<span class="number">1</span>];</span><br><span class="line">    <span class="keyword">if</span> (board[x][y]==<span class="string">&#x27;M&#x27;</span>) &#123;</span><br><span class="line">        board[x][y]=<span class="string">&#x27;X&#x27;</span>;</span><br><span class="line">        <span class="keyword">return</span> board;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">boolean</span>[][] visit=<span class="keyword">new</span> <span class="keyword">boolean</span>[board.length][board[<span class="number">0</span>].length];</span><br><span class="line">    dfs(board,x,y,visit);</span><br><span class="line">    <span class="keyword">return</span> board;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">char</span>[][] board,<span class="keyword">int</span> x,<span class="keyword">int</span> y,<span class="keyword">boolean</span>[][] visit)</span></span>&#123;</span><br><span class="line">    visit[x][y]=<span class="keyword">true</span>;</span><br><span class="line">    <span class="keyword">int</span> count=getRoundBoom(board,x,y);</span><br><span class="line">    <span class="keyword">if</span>(count!=<span class="number">0</span>)&#123;</span><br><span class="line">        board[x][y]=(<span class="keyword">char</span>)(count+<span class="string">&#x27;0&#x27;</span>);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    board[x][y]=<span class="string">&#x27;B&#x27;</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;<span class="number">8</span>;i++) &#123;</span><br><span class="line">        <span class="keyword">int</span> nx=x+direction[i][<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">int</span> ny=y+direction[i][<span class="number">1</span>];</span><br><span class="line">        <span class="keyword">if</span> (isValid(board,nx,ny) &amp;&amp; !visit[nx][ny] &amp;&amp; board[nx][ny]!=<span class="string">&#x27;M&#x27;</span>) &#123;</span><br><span class="line">            dfs(board,nx,ny,visit);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getRoundBoom</span><span class="params">(<span class="keyword">char</span>[][] board,<span class="keyword">int</span> x,<span class="keyword">int</span> y)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> count=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;<span class="number">8</span>;i++) &#123;</span><br><span class="line">        <span class="keyword">int</span> nx=x+direction[i][<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">int</span> ny=y+direction[i][<span class="number">1</span>];</span><br><span class="line">        <span class="keyword">if</span> (isValid(board,nx,ny) &amp;&amp; board[nx][ny]==<span class="string">&#x27;M&#x27;</span>) &#123;</span><br><span class="line">            count++;</span><br><span class="line">        &#125;   </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> count;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isValid</span><span class="params">(<span class="keyword">final</span> <span class="keyword">char</span>[][] board,<span class="keyword">int</span> x,<span class="keyword">int</span> y)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> x&gt;=<span class="number">0</span> &amp;&amp; x&lt;board.length &amp;&amp; y&gt;=<span class="number">0</span> &amp;&amp; y&lt;board[<span class="number">0</span>].length;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="695-岛屿的最大面积"><a href="#695-岛屿的最大面积" class="headerlink" title="695. 岛屿的最大面积"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/max-area-of-island/" >695. 岛屿的最大面积<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个包含了一些 0 和 1的非空二维数组 <code>grid</code> , 一个 <code>岛屿</code> 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合。你可以假设二维矩阵的四个边缘都被水包围着。</p>
<p>找到给定的二维数组中最大的岛屿面积。(如果没有岛屿，则返回面积为0)</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">[[<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>],</span><br><span class="line"> [<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>],</span><br><span class="line"> [<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>],</span><br><span class="line"> [<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>],</span><br><span class="line"> [<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>],</span><br><span class="line"> [<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>],</span><br><span class="line"> [<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>],</span><br><span class="line"> [<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>]]</span><br></pre></td></tr></table></figure>

<p>对于上面这个给定矩阵应返回 6。注意答案不应该是11，因为岛屿只能包含水平或垂直的四个方向的 <code>‘1’</code>。</p>
<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">[[<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>]]</span><br></pre></td></tr></table></figure>


<p>对于上面这个给定的矩阵, 返回 0</p>
<p><strong>注意:</strong> 给定的矩阵grid 的长度和宽度都不超过 50。</p>
<p><strong>解法一</strong></p>
<p>和上面 <a href="#200-%E5%B2%9B%E5%B1%BF%E6%95%B0%E9%87%8F">200题岛屿的数量</a>很类似，不过还是有所不同，这里要计算的是最大的面积</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">int</span>[][] direction=&#123;&#123;<span class="number">0</span>,<span class="number">1</span>&#125;,&#123;<span class="number">0</span>,-<span class="number">1</span>&#125;,&#123;<span class="number">1</span>,<span class="number">0</span>&#125;,&#123;-<span class="number">1</span>,<span class="number">0</span>&#125;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxAreaOfIsland</span><span class="params">(<span class="keyword">int</span>[][] grid)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (grid==<span class="keyword">null</span> || grid.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> max;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">boolean</span>[][] visit=<span class="keyword">new</span> <span class="keyword">boolean</span>[grid.length][grid[<span class="number">0</span>].length];</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;grid.length;i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;grid[<span class="number">0</span>].length;j++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (grid[i][j]==<span class="number">1</span> &amp;&amp;!visit[i][j]) &#123;</span><br><span class="line">                <span class="keyword">int</span> t=dfs(grid,i,j,visit);</span><br><span class="line">                max=max&gt;t?max:t;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> max;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> max=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span>[][] grid,<span class="keyword">int</span> x,<span class="keyword">int</span> y,<span class="keyword">boolean</span>[][] visit)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> temp=<span class="number">1</span>;</span><br><span class="line">    visit[x][y]=<span class="keyword">true</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;direction.length;i++) &#123;</span><br><span class="line">        <span class="keyword">int</span> nx=x+direction[i][<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">int</span> ny=y+direction[i][<span class="number">1</span>];</span><br><span class="line">        <span class="keyword">if</span> (isValid(grid,nx,ny) &amp;&amp; grid[nx][ny]==<span class="number">1</span> &amp;&amp; !visit[nx][ny]) &#123;</span><br><span class="line">            <span class="comment">//将4个方向的符合条件的数量加起来</span></span><br><span class="line">            temp+=dfs(grid,nx,ny,visit);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> temp;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isValid</span><span class="params">(<span class="keyword">final</span> <span class="keyword">int</span>[][] grid,<span class="keyword">int</span> x,<span class="keyword">int</span> y)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> x&gt;=<span class="number">0</span> &amp;&amp; x&lt;grid.length &amp;&amp; y&gt;=<span class="number">0</span> &amp;&amp; y&lt;grid[<span class="number">0</span>].length;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>最开始直接在dfs函数里面用count计数，居然还过了600多个case…..惊了，那种做法完全是错的，说实话有点不太习惯写有返回值的递归</p>
<h2 id="547-朋友圈"><a href="#547-朋友圈" class="headerlink" title="547. 朋友圈"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/friend-circles/" >547. 朋友圈<i class="fas fa-external-link-alt"></i></a></h2><p>班上有 N 名学生。其中有些人是朋友，有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友，B 是 C 的朋友，那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈，是指所有朋友的集合。</p>
<p>给定一个 N * N 的矩阵 M，表示班级中学生之间的朋友关系。如果M[i] [j] = 1，表示已知第 i 个和 j 个学生互为朋友关系，否则为不知道。你必须输出所有学生中的已知的朋友圈总数。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: </span><br><span class="line">[[<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>],</span><br><span class="line"> [<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>],</span><br><span class="line"> [<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>]]</span><br><span class="line">输出: <span class="number">2</span> </span><br><span class="line">说明：已知学生<span class="number">0</span>和学生<span class="number">1</span>互为朋友，他们在一个朋友圈。</span><br><span class="line">第<span class="number">2</span>个学生自己在一个朋友圈。所以返回<span class="number">2</span>。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: </span><br><span class="line">[[<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>],</span><br><span class="line"> [<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>],</span><br><span class="line"> [<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>]]</span><br><span class="line">输出: <span class="number">1</span></span><br><span class="line">说明：已知学生<span class="number">0</span>和学生<span class="number">1</span>互为朋友，学生<span class="number">1</span>和学生<span class="number">2</span>互为朋友，所以学生<span class="number">0</span>和学生<span class="number">2</span>也是朋友，所以他们三个在一个朋友圈，返回<span class="number">1</span>。</span><br></pre></td></tr></table></figure>

<p><strong>注意：</strong></p>
<ul>
<li>N 在[1,200]的范围内。</li>
<li>对于所有学生，有M[i] [i] = 1。</li>
<li>如果有M[i] [j] = 1，则有M[j] [i] = 1。</li>
</ul>
<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findCircleNum</span><span class="params">(<span class="keyword">int</span>[][] M)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (M==<span class="keyword">null</span> || M.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">boolean</span>[] visit=<span class="keyword">new</span> <span class="keyword">boolean</span>[M.length];</span><br><span class="line">    <span class="keyword">int</span> count=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;M.length;i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!visit[i]) &#123;</span><br><span class="line">            dfs(M,visit,i);</span><br><span class="line">            count++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> count;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//一共m.length个人</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span>[][] M,<span class="keyword">boolean</span>[] visit,<span class="keyword">int</span> index)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//标记index号学生已经访问过</span></span><br><span class="line">    visit[index]=<span class="keyword">true</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;M.length;i++) &#123;</span><br><span class="line">        <span class="comment">//index和i是好朋友</span></span><br><span class="line">        <span class="keyword">if</span> (M[index][i]==<span class="number">1</span> &amp;&amp; !visit[i]) &#123;</span><br><span class="line">            <span class="comment">//递归标记i的好朋友,形成朋友圈</span></span><br><span class="line">            dfs(M,visit,i);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这题不知道为啥，一开始题目没搞明白。。。。去纠结那个矩阵去了，没理解好题目的意思，其实跟那个N*N的矩阵没啥关系，主要是N个人，对每个人进行dfs找到与他们相关的人，做好统计就ok，和上面的 200题也很类似</p>
<h2 id="1219-黄金矿工"><a href="#1219-黄金矿工" class="headerlink" title="1219. 黄金矿工"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/path-with-maximum-gold/" >1219. 黄金矿工<i class="fas fa-external-link-alt"></i></a></h2><p>你要开发一座金矿，地质勘测学家已经探明了这座金矿中的资源分布，并用大小为 m * n 的网格 grid 进行了标注。每个单元格中的整数就表示这一单元格中的黄金数量；如果该单元格是空的，那么就是 0。</p>
<p>为了使收益最大化，矿工需要按以下规则来开采黄金：</p>
<ul>
<li>每当矿工进入一个单元，就会收集该单元格中的所有黄金。</li>
<li>矿工每次可以从当前位置向上下左右四个方向走。</li>
<li>每个单元格<strong>只能被开采（进入）一次</strong>。</li>
<li><strong>不得开采</strong>（进入）黄金数目为 0 的单元格。</li>
<li>矿工可以从网格中 <strong>任意一个</strong> 有黄金的单元格出发或者是停止。  </li>
</ul>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：grid = [[<span class="number">0</span>,<span class="number">6</span>,<span class="number">0</span>],[<span class="number">5</span>,<span class="number">8</span>,<span class="number">7</span>],[<span class="number">0</span>,<span class="number">9</span>,<span class="number">0</span>]]</span><br><span class="line">输出：<span class="number">24</span></span><br><span class="line">解释：</span><br><span class="line">[[<span class="number">0</span>,<span class="number">6</span>,<span class="number">0</span>],</span><br><span class="line"> [<span class="number">5</span>,<span class="number">8</span>,<span class="number">7</span>],</span><br><span class="line"> [<span class="number">0</span>,<span class="number">9</span>,<span class="number">0</span>]]</span><br><span class="line">一种收集最多黄金的路线是：<span class="number">9</span> -&gt; <span class="number">8</span> -&gt; <span class="number">7</span>。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：grid = [[<span class="number">1</span>,<span class="number">0</span>,<span class="number">7</span>],[<span class="number">2</span>,<span class="number">0</span>,<span class="number">6</span>],[<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>],[<span class="number">0</span>,<span class="number">3</span>,<span class="number">0</span>],[<span class="number">9</span>,<span class="number">0</span>,<span class="number">20</span>]]</span><br><span class="line">输出：<span class="number">28</span></span><br><span class="line">解释：</span><br><span class="line">[[<span class="number">1</span>,<span class="number">0</span>,<span class="number">7</span>],</span><br><span class="line"> [<span class="number">2</span>,<span class="number">0</span>,<span class="number">6</span>],</span><br><span class="line"> [<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>],</span><br><span class="line"> [<span class="number">0</span>,<span class="number">3</span>,<span class="number">0</span>],</span><br><span class="line"> [<span class="number">9</span>,<span class="number">0</span>,<span class="number">20</span>]]</span><br><span class="line">一种收集最多黄金的路线是：<span class="number">1</span> -&gt; <span class="number">2</span> -&gt; <span class="number">3</span> -&gt; <span class="number">4</span> -&gt; <span class="number">5</span> -&gt; <span class="number">6</span> -&gt; <span class="number">7</span>。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>-<code>1 &lt;= grid.length, grid[i].length &lt;= 15</code></li>
<li><code>0 &lt;= grid[i][j] &lt;= 100</code></li>
<li>最多 25 个单元格中有黄金。 </li>
</ul>
<p><strong>解法一</strong></p>
<p>这题还是挺有意思的，填补了我一点二维平面回溯的空缺，其实也很简单（改了好几个小时还好意思说这种话😂）</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">int</span>[][] direction=&#123;&#123;<span class="number">0</span>,<span class="number">1</span>&#125;,&#123;<span class="number">1</span>,<span class="number">0</span>&#125;,&#123;<span class="number">0</span>,-<span class="number">1</span>&#125;,&#123;-<span class="number">1</span>,<span class="number">0</span>&#125;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getMaximumGold</span><span class="params">(<span class="keyword">int</span>[][] grid)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> max=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">boolean</span>[][] visit=<span class="keyword">new</span> <span class="keyword">boolean</span>[grid.length][grid[<span class="number">0</span>].length];</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;grid.length;i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;grid[<span class="number">0</span>].length;j++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (grid[i][j]&gt;<span class="number">0</span>) &#123;</span><br><span class="line">                max=Math.max(dfs(grid,i,j,visit),max);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> max;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//求出从x,y开始所能获得的最大的收益，记得回溯状态，后面的节点还需要遍历</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span>[][] grid,<span class="keyword">int</span> x,<span class="keyword">int</span> y,<span class="keyword">boolean</span>[][] visit)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> maxGlod=grid[x][y]; <span class="comment">//一开始这里写的0...排了半天的错</span></span><br><span class="line">    visit[x][y]=<span class="keyword">true</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;direction.length;i++) &#123;</span><br><span class="line">        <span class="keyword">int</span> nx=x+direction[i][<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">int</span> ny=y+direction[i][<span class="number">1</span>];</span><br><span class="line">        <span class="keyword">if</span> (isValid(grid,nx,ny) &amp;&amp; !visit[nx][ny] &amp;&amp; grid[nx][ny]&gt;<span class="number">0</span>) &#123;</span><br><span class="line">            <span class="comment">//求向4个方向扩展的最大值</span></span><br><span class="line">            maxGlod=Math.max(dfs(grid,nx,ny,visit)+grid[x][y],maxGlod);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    visit[x][y]=<span class="keyword">false</span>;</span><br><span class="line">    <span class="keyword">return</span> maxGlod;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isValid</span><span class="params">(<span class="keyword">final</span> <span class="keyword">int</span>[][] grid,<span class="keyword">int</span> x,<span class="keyword">int</span> y)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> x&gt;=<span class="number">0</span> &amp;&amp; x&lt;grid.length &amp;&amp; y&gt;=<span class="number">0</span> &amp;&amp; y&lt;grid[<span class="number">0</span>].length;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>思路其实也很简单，对每个有金矿的点进行dfs计算路径上的金矿和就ok了，但是这题有一个很关键的条件，不能回头，下过的金矿是不能第二次再进入的，不然这题就和前面的 [695. 岛屿最大面积](##695. 岛屿的最大面积)一样了，所以很显然这题是需要状态的回溯的，访问过的节点，后面的节点还是可能需要遍历的，最开始写的一个bug就是代码中提到的，那里一开始写的0…然后排错排了好长时间。。。菜啊</p>
<h2 id="面试题13-机器人的运动范围"><a href="#面试题13-机器人的运动范围" class="headerlink" title="面试题13. 机器人的运动范围"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/" >面试题13. 机器人的运动范围<i class="fas fa-external-link-alt"></i></a></h2><p>地上有一个m行n列的方格，从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动，它每次可以向左、右、上、下移动一格（不能移动到方格外），也不能进入行坐标和列坐标的数位之和大于k的格子。例如，当k为18时，机器人能够进入方格 [35, 37] ，因为3+5+3+7=18。但它不能进入方格 [35, 38]，因为3+5+3+8=19。请问该机器人能够到达多少个格子？</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：m = <span class="number">2</span>, n = <span class="number">3</span>, k = <span class="number">1</span></span><br><span class="line">输出：<span class="number">3</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：m = <span class="number">3</span>, n = <span class="number">1</span>, k = <span class="number">0</span></span><br><span class="line">输出：<span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li><code>1 &lt;= n,m &lt;= 100</code></li>
<li><code>0 &lt;= k &lt;= 20</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>一开始没认真看例子，以为是求不能回头一次能走的最多的格子，原基础上稍微改一下就可以了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">int</span>[][] direction=&#123;&#123;<span class="number">1</span>,<span class="number">0</span>&#125;,&#123;<span class="number">0</span>,<span class="number">1</span>&#125;,&#123;<span class="number">0</span>,-<span class="number">1</span>&#125;,&#123;-<span class="number">1</span>,<span class="number">0</span>&#125;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">movingCount</span><span class="params">(<span class="keyword">int</span> m, <span class="keyword">int</span> n, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> dfs(m,n,<span class="number">0</span>,<span class="number">0</span>,k,<span class="keyword">new</span> <span class="keyword">boolean</span>[m][n]);   </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span> m,<span class="keyword">int</span> n,<span class="keyword">int</span> x,<span class="keyword">int</span> y,<span class="keyword">int</span> k,<span class="keyword">boolean</span>[][] visit)</span></span>&#123;</span><br><span class="line">    visit[x][y]=<span class="keyword">true</span>;</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;direction.length;i++) &#123;</span><br><span class="line">        <span class="keyword">int</span> nx=x+direction[i][<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">int</span> ny=y+direction[i][<span class="number">1</span>];</span><br><span class="line">        <span class="keyword">if</span>(valid(m,n,nx,ny,k) &amp;&amp; !visit[nx][ny])&#123;</span><br><span class="line">            <span class="comment">//以为是求最长的距离.....</span></span><br><span class="line">            <span class="comment">//res=Math.max(dfs(m,n,nx,ny,k,visit)+1,res);</span></span><br><span class="line">            res+=dfs(m,n,nx,ny,k,visit);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//visit[x][y]=false;</span></span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">valid</span><span class="params">(<span class="keyword">int</span> m,<span class="keyword">int</span> n,<span class="keyword">int</span> x,<span class="keyword">int</span> y,<span class="keyword">int</span> k)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(x&lt;<span class="number">0</span> || x&gt;=m || y&lt;<span class="number">0</span> || y&gt;=n)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line">    <span class="comment">//35 37</span></span><br><span class="line">    <span class="keyword">while</span>(x!=<span class="number">0</span>)&#123;</span><br><span class="line">        res+=(x%<span class="number">10</span>);</span><br><span class="line">        x/=<span class="number">10</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">while</span>(y!=<span class="number">0</span>)&#123;</span><br><span class="line">        res+=(y%<span class="number">10</span>);</span><br><span class="line">        y/=<span class="number">10</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res&lt;=k;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="1020-飞地的数量"><a href="#1020-飞地的数量" class="headerlink" title="1020. 飞地的数量"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/number-of-enclaves/" >1020. 飞地的数量<i class="fas fa-external-link-alt"></i></a></h2><p>给出一个二维数组 <code>A</code>，每个单元格为 0（代表海）或 1（代表陆地）。</p>
<p>移动是指在陆地上从一个地方走到另一个地方（朝四个方向之一）或离开网格的边界。</p>
<p>返回网格中<strong>无法</strong>在任意次数的移动中离开网格边界的陆地单元格的数量。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：[[<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>],[<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>],[<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>],[<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>]]</span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释： </span><br><span class="line">有三个 <span class="number">1</span> 被 <span class="number">0</span> 包围。一个 <span class="number">1</span> 没有被包围，因为它在边界上。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：[[<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>],[<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>],[<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>],[<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>]]</span><br><span class="line">输出：<span class="number">0</span></span><br><span class="line">解释：</span><br><span class="line">所有 <span class="number">1</span> 都在边界上或可以到达边界。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li><code>1 &lt;= A.length &lt;= 500</code></li>
<li><code>1 &lt;= A[i].length &lt;= 500</code></li>
<li><code>0 &lt;= A[i][j] &lt;= 1</code></li>
<li>所有行的大小都相同</li>
</ol>
<p><strong>解法一</strong></p>
<p>dfs搜索就完事儿了，水题</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//DFS</span></span><br><span class="line"><span class="keyword">int</span>[][] dir=&#123;&#123;<span class="number">1</span>,<span class="number">0</span>&#125;,&#123;<span class="number">0</span>,<span class="number">1</span>&#125;,&#123;-<span class="number">1</span>,<span class="number">0</span>&#125;,&#123;<span class="number">0</span>,-<span class="number">1</span>&#125;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">numEnclaves</span><span class="params">(<span class="keyword">int</span>[][] A)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(A==<span class="keyword">null</span> || A.length&lt;=<span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> N=A.length;</span><br><span class="line">    <span class="keyword">int</span> M=A[<span class="number">0</span>].length;</span><br><span class="line">    <span class="keyword">boolean</span>[][] visit=<span class="keyword">new</span> <span class="keyword">boolean</span>[N][M];</span><br><span class="line">    <span class="keyword">int</span> a=<span class="number">0</span>,b=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(a&lt;N)&#123; <span class="comment">//左右边界</span></span><br><span class="line">        <span class="keyword">if</span>(A[a][<span class="number">0</span>]==<span class="number">1</span> &amp;&amp; !visit[a][<span class="number">0</span>]) dfs(A,a,<span class="number">0</span>,visit);</span><br><span class="line">        <span class="keyword">if</span>(A[a][M-<span class="number">1</span>]==<span class="number">1</span> &amp;&amp; !visit[a][M-<span class="number">1</span>]) dfs(A,a,M-<span class="number">1</span>,visit);</span><br><span class="line">        a++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">while</span>(b&lt;M)&#123; <span class="comment">//上下边界</span></span><br><span class="line">        <span class="keyword">if</span>(A[<span class="number">0</span>][b]==<span class="number">1</span>&amp;&amp; !visit[<span class="number">0</span>][b]) dfs(A,<span class="number">0</span>,b,visit);</span><br><span class="line">        <span class="keyword">if</span>(A[N-<span class="number">1</span>][b]==<span class="number">1</span>&amp;&amp; !visit[N-<span class="number">1</span>][b]) dfs(A,N-<span class="number">1</span>,b,visit);</span><br><span class="line">        b++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;N;i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;M;j++) &#123;</span><br><span class="line">            <span class="keyword">if</span>(A[i][j]==<span class="number">1</span> &amp;&amp; !visit[i][j])&#123;</span><br><span class="line">                res++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span>[][] A,<span class="keyword">int</span> x,<span class="keyword">int</span> y,<span class="keyword">boolean</span>[][] visit)</span></span>&#123;</span><br><span class="line">    visit[x][y]=<span class="keyword">true</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;dir.length;i++) &#123;</span><br><span class="line">        <span class="keyword">int</span> nx=x+dir[i][<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">int</span> ny=y+dir[i][<span class="number">1</span>];</span><br><span class="line">        <span class="keyword">if</span>(valid(A,nx,ny) &amp;&amp; !visit[nx][ny] &amp;&amp; A[nx][ny]==<span class="number">1</span>)&#123;</span><br><span class="line">            dfs(A,nx,ny,visit);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">valid</span><span class="params">(<span class="keyword">final</span> <span class="keyword">int</span>[][] A,<span class="keyword">int</span> x,<span class="keyword">int</span> y)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> x&gt;=<span class="number">0</span> &amp;&amp; x&lt;A.length &amp;&amp; y&gt;=<span class="number">0</span> &amp;&amp; y&lt;A[<span class="number">0</span>].length;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>并查集的解法放在 <a href="http://imlgw.top/2020/02/02/bing-cha-ji/">并查集专题</a> 中</p>
<h2 id="934-最短的桥"><a href="#934-最短的桥" class="headerlink" title="934. 最短的桥"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/shortest-bridge/" >934. 最短的桥<i class="fas fa-external-link-alt"></i></a></h2><p>在给定的二维二进制数组 <code>A</code> 中，存在两座岛。（岛是由四面相连的 <code>1</code> 形成的一个最大组。）</p>
<p>现在，我们可以将 <code>0</code> 变为 <code>1</code>，以使两座岛连接起来，变成一座岛。</p>
<p>返回必须翻转的 <code>0</code> 的最小数目。（可以保证答案至少是 1。）</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：[[<span class="number">0</span>,<span class="number">1</span>],[<span class="number">1</span>,<span class="number">0</span>]]</span><br><span class="line">输出：<span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：[[<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>],[<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>],[<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>]]</span><br><span class="line">输出：<span class="number">2</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：[[<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>],[<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>],[<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>],[<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>],[<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>]]</span><br><span class="line">输出：<span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li><code>1 &lt;= A.length = A[0].length &lt;= 100</code></li>
<li><code>A[i][j] == 0</code> 或 <code>A[i][j] == 1</code></li>
</ol>
<p><strong>解法一</strong></p>
<p>这题还挺有意思的，dfs+bfs都要用，单纯的深搜和广搜很难搞，先dfs给一个岛做标记，然后多源bfs找距离最近的另一个岛</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">int</span>[] dir = &#123;<span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>, -<span class="number">1</span>, <span class="number">0</span>&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">shortestBridge</span><span class="params">(<span class="keyword">int</span>[][] A)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">boolean</span>[][] mark = <span class="keyword">new</span> <span class="keyword">boolean</span>[A.length][A[<span class="number">0</span>].length];</span><br><span class="line">    lable:</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; A.length; i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; A[<span class="number">0</span>].length; j++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (A[i][j] == <span class="number">1</span>) &#123;</span><br><span class="line">                dfs(A, i, j, mark);</span><br><span class="line">                <span class="keyword">break</span> lable;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    Queue&lt;Pair&gt; queue = <span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; A.length; i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; A[<span class="number">0</span>].length; j++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (A[i][j] == <span class="number">1</span> &amp;&amp; mark[i][j]) &#123;</span><br><span class="line">                queue.add(<span class="keyword">new</span> Pair(i, j, <span class="number">0</span>));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">while</span> (!queue.isEmpty()) &#123;</span><br><span class="line">        Pair pair = queue.poll();</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">4</span>; i++) &#123;</span><br><span class="line">            <span class="keyword">int</span> nx = pair.x + dir[i];</span><br><span class="line">            <span class="keyword">int</span> ny = pair.y + dir[i + <span class="number">1</span>];</span><br><span class="line">            <span class="keyword">if</span> (valid(A, nx, ny) &amp;&amp; !mark[nx][ny]) &#123;</span><br><span class="line">                <span class="keyword">if</span> (A[nx][ny] == <span class="number">1</span>) &#123;</span><br><span class="line">                    <span class="keyword">return</span> pair.step;</span><br><span class="line">                &#125;</span><br><span class="line">                mark[nx][ny] = <span class="keyword">true</span>;</span><br><span class="line">                queue.add(<span class="keyword">new</span> Pair(nx, ny, pair.step + <span class="number">1</span>));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span>[][] A, <span class="keyword">int</span> x, <span class="keyword">int</span> y, <span class="keyword">boolean</span>[][] mark)</span> </span>&#123;</span><br><span class="line">    mark[x][y] = <span class="keyword">true</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">4</span>; i++) &#123;</span><br><span class="line">        <span class="keyword">int</span> nx = x + dir[i];</span><br><span class="line">        <span class="keyword">int</span> ny = y + dir[i + <span class="number">1</span>];</span><br><span class="line">        <span class="keyword">if</span> (valid(A, nx, ny) &amp;&amp; A[nx][ny] == <span class="number">1</span> &amp;&amp; !mark[nx][ny]) &#123;</span><br><span class="line">            dfs(A, nx, ny, mark);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">valid</span><span class="params">(<span class="keyword">int</span>[][] A, <span class="keyword">int</span> x, <span class="keyword">int</span> y)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> x &gt;= <span class="number">0</span> &amp;&amp; x &lt; A.length &amp;&amp; y &gt;= <span class="number">0</span> &amp;&amp; y &lt; A[<span class="number">0</span>].length;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Pair</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> x, y;</span><br><span class="line">    <span class="keyword">int</span> step;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Pair</span><span class="params">(<span class="keyword">int</span> x, <span class="keyword">int</span> y, <span class="keyword">int</span> step)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.x = x;</span><br><span class="line">        <span class="keyword">this</span>.y = y;</span><br><span class="line">        <span class="keyword">this</span>.step = step;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="733-图像渲染"><a href="#733-图像渲染" class="headerlink" title="733. 图像渲染"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/flood-fill/" >733. 图像渲染<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>简单</strong></p>
<p>有一幅以二维整数数组表示的图画，每一个整数表示该图画的像素值大小，数值在 0 到 65535 之间。</p>
<p>给你一个坐标 <code>(sr, sc)</code> 表示图像渲染开始的像素值（行 ，列）和一个新的颜色值 <code>newColor</code>，让你重新上色这幅图像。</p>
<p>为了完成上色工作，从初始坐标开始，记录初始坐标的上下左右四个方向上像素值与初始坐标相同的相连像素点，接着再记录这四个方向上符合条件的像素点与他们对应四个方向上像素值与初始坐标相同的相连像素点，……，重复该过程。将所有有记录的像素点的颜色值改为新的颜色值。</p>
<p>最后返回经过上色渲染后的图像。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入: </span><br><span class="line">image = [[<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>],[<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>],[<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>]]</span><br><span class="line">sr = <span class="number">1</span>, sc = <span class="number">1</span>, newColor = <span class="number">2</span></span><br><span class="line">输出: [[<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>],[<span class="number">2</span>,<span class="number">2</span>,<span class="number">0</span>],[<span class="number">2</span>,<span class="number">0</span>,<span class="number">1</span>]]</span><br><span class="line">解析: </span><br><span class="line">在图像的正中间，(坐标(sr,sc)=(<span class="number">1</span>,<span class="number">1</span>)),</span><br><span class="line">在路径上所有符合条件的像素点的颜色都被更改成<span class="number">2</span>。</span><br><span class="line">注意，右下角的像素没有更改为<span class="number">2</span>，</span><br><span class="line">因为它不是在上下左右四个方向上与初始点相连的像素点。</span><br></pre></td></tr></table></figure>

<p><strong>注意:</strong></p>
<ul>
<li>  <code>image</code> 和 <code>image[0]</code> 的长度在范围 <code>[1, 50]</code> 内。</li>
<li>  给出的初始点将满足 <code>0 &lt;= sr &lt; image.length</code> 和 <code>0 &lt;= sc &lt; image[0].length</code>。</li>
<li>  <code>image[i][j]</code> 和 <code>newColor</code> 表示的颜色值在范围 <code>[0, 65535]</code>内。</li>
</ul>
<p><strong>解法一</strong></p>
<p>经典搜索，没啥好说的</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">floodFill</span><span class="params">(image [][]<span class="keyword">int</span>, sr <span class="keyword">int</span>, sc <span class="keyword">int</span>, newColor <span class="keyword">int</span>)</span> [][]<span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> m = <span class="built_in">len</span>(image)</span><br><span class="line">    <span class="keyword">var</span> n = <span class="built_in">len</span>(image[<span class="number">0</span>])</span><br><span class="line">    <span class="keyword">var</span> dir = []<span class="keyword">int</span>&#123;<span class="number">1</span>, <span class="number">0</span>, <span class="number">-1</span>, <span class="number">0</span>, <span class="number">1</span>&#125;</span><br><span class="line">    <span class="keyword">var</span> visit = <span class="built_in">make</span>([][]<span class="keyword">bool</span>, m)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; m; i++ &#123;</span><br><span class="line">        visit[i] = <span class="built_in">make</span>([]<span class="keyword">bool</span>, n)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> src = image[sr][sc]</span><br><span class="line">    <span class="keyword">var</span> valid = <span class="function"><span class="keyword">func</span><span class="params">(x <span class="keyword">int</span>, y <span class="keyword">int</span>)</span> <span class="title">bool</span></span> &#123;</span><br><span class="line">        <span class="keyword">return</span> x &gt;= <span class="number">0</span> &amp;&amp; x &lt; m &amp;&amp; y &gt;= <span class="number">0</span> &amp;&amp; y &lt; n</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(x <span class="keyword">int</span>, y <span class="keyword">int</span>)</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(x <span class="keyword">int</span>, y <span class="keyword">int</span>)</span></span> &#123;</span><br><span class="line">        visit[x][y] = <span class="literal">true</span></span><br><span class="line">        image[x][y] = newColor</span><br><span class="line">        <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="number">4</span>; i++ &#123;</span><br><span class="line">            <span class="keyword">var</span> nx = x + dir[i]</span><br><span class="line">            <span class="keyword">var</span> ny = y + dir[i+<span class="number">1</span>]</span><br><span class="line">            <span class="keyword">if</span> valid(nx, ny) &amp;&amp; !visit[nx][ny] &amp;&amp; image[nx][ny] == src &#123;</span><br><span class="line">                dfs(nx, ny)</span><br><span class="line">            &#125; </span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(sr, sc)</span><br><span class="line">    <span class="keyword">return</span> image</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>通过染色的情况判断是否遍历过节点，节省visit数组</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">floodFill</span><span class="params">(image [][]<span class="keyword">int</span>, sr <span class="keyword">int</span>, sc <span class="keyword">int</span>, newColor <span class="keyword">int</span>)</span> [][]<span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> m = <span class="built_in">len</span>(image)</span><br><span class="line">    <span class="keyword">var</span> n = <span class="built_in">len</span>(image[<span class="number">0</span>])</span><br><span class="line">    <span class="keyword">var</span> dir = []<span class="keyword">int</span>&#123;<span class="number">1</span>, <span class="number">0</span>, <span class="number">-1</span>, <span class="number">0</span>, <span class="number">1</span>&#125;</span><br><span class="line">    <span class="keyword">var</span> src = image[sr][sc]</span><br><span class="line">    <span class="keyword">var</span> valid = <span class="function"><span class="keyword">func</span><span class="params">(x <span class="keyword">int</span>, y <span class="keyword">int</span>)</span> <span class="title">bool</span></span> &#123;</span><br><span class="line">        <span class="keyword">return</span> x &gt;= <span class="number">0</span> &amp;&amp; x &lt; m &amp;&amp; y &gt;= <span class="number">0</span> &amp;&amp; y &lt; n</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(x <span class="keyword">int</span>, y <span class="keyword">int</span>)</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(x <span class="keyword">int</span>, y <span class="keyword">int</span>)</span></span> &#123;</span><br><span class="line">        image[x][y] = newColor</span><br><span class="line">        <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="number">4</span>; i++ &#123;</span><br><span class="line">            <span class="keyword">var</span> nx = x + dir[i]</span><br><span class="line">            <span class="keyword">var</span> ny = y + dir[i+<span class="number">1</span>]</span><br><span class="line">            <span class="keyword">if</span> valid(nx, ny) &amp;&amp; image[nx][ny]!=newColor &amp;&amp; image[nx][ny] == src &#123;</span><br><span class="line">                dfs(nx, ny)</span><br><span class="line">            &#125; </span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(sr, sc)</span><br><span class="line">    <span class="keyword">return</span> image</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="1559-二维网格图中探测环"><a href="#1559-二维网格图中探测环" class="headerlink" title="1559. 二维网格图中探测环"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/detect-cycles-in-2d-grid/" >1559. 二维网格图中探测环<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>困难</strong></p>
<p>给你一个二维字符网格数组 <code>grid</code> ，大小为 <code>m x n</code> ，你需要检查 <code>grid</code> 中是否存在 <strong>相同值</strong> 形成的环。</p>
<p>一个环是一条开始和结束于同一个格子的长度 <strong>大于等于 4</strong> 的路径。对于一个给定的格子，你可以移动到它上、下、左、右四个方向相邻的格子之一，可以移动的前提是这两个格子有 **相同的值 **。</p>
<p>同时，你也不能回到上一次移动时所在的格子。比方说，环  <code>(1, 1) -&gt; (1, 2) -&gt; (1, 1)</code> 是不合法的，因为从 <code>(1, 2)</code> 移动到 <code>(1, 1)</code> 回到了上一次移动时的格子。</p>
<p>如果 <code>grid</code> 中有相同值形成的环，请你返回 <code>true</code> ，否则返回 <code>false</code> 。</p>
<p><strong>示例 1：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2020/12/16/IF9PVSHoOXtZwRr.png"
                     
                ></p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line">输入：grid = [[<span class="string">&quot;a&quot;</span>,<span class="string">&quot;a&quot;</span>,<span class="string">&quot;a&quot;</span>,<span class="string">&quot;a&quot;</span>],[<span class="string">&quot;a&quot;</span>,<span class="string">&quot;b&quot;</span>,<span class="string">&quot;b&quot;</span>,<span class="string">&quot;a&quot;</span>],[<span class="string">&quot;a&quot;</span>,<span class="string">&quot;b&quot;</span>,<span class="string">&quot;b&quot;</span>,<span class="string">&quot;a&quot;</span>],[<span class="string">&quot;a&quot;</span>,<span class="string">&quot;a&quot;</span>,<span class="string">&quot;a&quot;</span>,<span class="string">&quot;a&quot;</span>]]</span><br><span class="line">输出：<span class="literal">true</span></span><br><span class="line">解释：如下图所示，有 <span class="number">2</span> 个用不同颜色标出来的环：</span><br></pre></td></tr></table></figure>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2020/12/16/8EJDuUPc2xMilBm.png"
                     
                ></p>
<p><strong>示例 2：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2020/12/16/eljrFPCzf4pgd6s.png"
                     
                ></p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line">输入：grid = [[<span class="string">&quot;c&quot;</span>,<span class="string">&quot;c&quot;</span>,<span class="string">&quot;c&quot;</span>,<span class="string">&quot;a&quot;</span>],[<span class="string">&quot;c&quot;</span>,<span class="string">&quot;d&quot;</span>,<span class="string">&quot;c&quot;</span>,<span class="string">&quot;c&quot;</span>],[<span class="string">&quot;c&quot;</span>,<span class="string">&quot;c&quot;</span>,<span class="string">&quot;e&quot;</span>,<span class="string">&quot;c&quot;</span>],[<span class="string">&quot;f&quot;</span>,<span class="string">&quot;c&quot;</span>,<span class="string">&quot;c&quot;</span>,<span class="string">&quot;c&quot;</span>]]</span><br><span class="line">输出：<span class="literal">true</span></span><br><span class="line">解释：如下图所示，只有高亮所示的一个合法环：</span><br></pre></td></tr></table></figure>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2020/12/16/9FfYxP7DSUBXEaG.png"
                     
                ></p>
<p><strong>示例 3：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2020/12/16/fAr1TEQNpumaXck.png"
                     
                ></p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line">输入：grid = [[<span class="string">&quot;a&quot;</span>,<span class="string">&quot;b&quot;</span>,<span class="string">&quot;b&quot;</span>],[<span class="string">&quot;b&quot;</span>,<span class="string">&quot;z&quot;</span>,<span class="string">&quot;b&quot;</span>],[<span class="string">&quot;b&quot;</span>,<span class="string">&quot;b&quot;</span>,<span class="string">&quot;a&quot;</span>]]</span><br><span class="line">输出：<span class="literal">false</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>  <code>m == grid.length</code></li>
<li>  <code>n == grid[i].length</code></li>
<li>  <code>1 &lt;= m &lt;= 500</code></li>
<li>  <code>1 &lt;= n &lt;= 500</code></li>
<li>  <code>grid</code> 只包含小写英文字母。</li>
</ul>
<p><strong>解法一</strong></p>
<p>33双周赛的T4，总体不是很难，dfs或者并查集都可以</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">containsCycle</span><span class="params">(grid [][]<span class="keyword">byte</span>)</span> <span class="title">bool</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> m, n = <span class="built_in">len</span>(grid), <span class="built_in">len</span>(grid[<span class="number">0</span>])</span><br><span class="line">    <span class="keyword">var</span> dir = [<span class="number">4</span>][<span class="number">2</span>]<span class="keyword">int</span>&#123;&#123;<span class="number">0</span>,<span class="number">1</span>&#125;,&#123;<span class="number">1</span>,<span class="number">0</span>&#125;,&#123;<span class="number">-1</span>,<span class="number">0</span>&#125;,&#123;<span class="number">0</span>,<span class="number">-1</span>&#125;&#125;</span><br><span class="line">    <span class="keyword">var</span> visit = <span class="built_in">make</span>([][]<span class="keyword">bool</span>, m)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; m; i++ &#123;</span><br><span class="line">        visit[i] = <span class="built_in">make</span>([]<span class="keyword">bool</span>, n)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> valid = <span class="function"><span class="keyword">func</span><span class="params">(x, y <span class="keyword">int</span>)</span> <span class="title">bool</span></span> &#123; <span class="keyword">return</span> x &gt;= <span class="number">0</span> &amp;&amp; x &lt; m &amp;&amp; y &gt;= <span class="number">0</span> &amp;&amp; y &lt; n&#125;</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span> <span class="params">(<span class="keyword">int</span>, <span class="keyword">int</span>, <span class="keyword">int</span>, <span class="keyword">int</span>)</span></span></span><br><span class="line">    <span class="keyword">var</span> res = <span class="literal">false</span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(preX <span class="keyword">int</span>, preY <span class="keyword">int</span>, x <span class="keyword">int</span>, y <span class="keyword">int</span>)</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> visit[x][y] || res&#123;</span><br><span class="line">            res = <span class="literal">true</span></span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        visit[x][y] = <span class="literal">true</span></span><br><span class="line">        <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="built_in">len</span>(dir); i++ &#123;</span><br><span class="line">            nx := x + dir[i][<span class="number">0</span>]</span><br><span class="line">            ny := y + dir[i][<span class="number">1</span>]</span><br><span class="line">            <span class="comment">//不走回头路</span></span><br><span class="line">            <span class="keyword">if</span> nx == preX &amp;&amp; ny == preY &#123;</span><br><span class="line">                <span class="keyword">continue</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> valid(nx, ny) &amp;&amp; grid[nx][ny] == grid[x][y] &#123;</span><br><span class="line">                dfs(x, y, nx, ny)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; m; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt; n; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> !visit[i][j] &#123;</span><br><span class="line">                dfs(i,j,i,j)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>并查集的解法，留着以后再来写</p>
<h2 id="332-重新安排行程"><a href="#332-重新安排行程" class="headerlink" title="332. 重新安排行程"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/reconstruct-itinerary/" >332. 重新安排行程<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>中等</strong></p>
<p>给定一个机票的字符串二维数组 <code>[from, to]</code>，子数组中的两个成员分别表示飞机出发和降落的机场地点，对该行程进行重新规划排序。所有这些机票都属于一个从 JFK（肯尼迪国际机场）出发的先生，所以该行程必须从 JFK 开始。</p>
<p><strong>提示：</strong></p>
<ol>
<li> 如果存在多种有效的行程，请你按字符自然排序返回最小的行程组合。例如，行程 [“JFK”, “LGA”] 与 [“JFK”, “LGB”] 相比就更小，排序更靠前</li>
<li> 所有的机场都用三个大写字母表示（机场代码）。</li>
<li> 假定所有机票至少存在一种合理的行程。</li>
<li> 所有的机票必须都用一次 且 只能用一次。</li>
</ol>
<p><strong>示例 1：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：[[<span class="string">&quot;MUC&quot;</span>, <span class="string">&quot;LHR&quot;</span>], [<span class="string">&quot;JFK&quot;</span>, <span class="string">&quot;MUC&quot;</span>], [<span class="string">&quot;SFO&quot;</span>, <span class="string">&quot;SJC&quot;</span>], [<span class="string">&quot;LHR&quot;</span>, <span class="string">&quot;SFO&quot;</span>]]</span><br><span class="line">输出：[<span class="string">&quot;JFK&quot;</span>, <span class="string">&quot;MUC&quot;</span>, <span class="string">&quot;LHR&quot;</span>, <span class="string">&quot;SFO&quot;</span>, <span class="string">&quot;SJC&quot;</span>]</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：[[<span class="string">&quot;JFK&quot;</span>,<span class="string">&quot;SFO&quot;</span>],[<span class="string">&quot;JFK&quot;</span>,<span class="string">&quot;ATL&quot;</span>],[<span class="string">&quot;SFO&quot;</span>,<span class="string">&quot;ATL&quot;</span>],[<span class="string">&quot;ATL&quot;</span>,<span class="string">&quot;JFK&quot;</span>],[<span class="string">&quot;ATL&quot;</span>,<span class="string">&quot;SFO&quot;</span>]]</span><br><span class="line">输出：[<span class="string">&quot;JFK&quot;</span>,<span class="string">&quot;ATL&quot;</span>,<span class="string">&quot;JFK&quot;</span>,<span class="string">&quot;SFO&quot;</span>,<span class="string">&quot;ATL&quot;</span>,<span class="string">&quot;SFO&quot;</span>]</span><br><span class="line">解释：另一种有效的行程是 [<span class="string">&quot;JFK&quot;</span>,<span class="string">&quot;SFO&quot;</span>,<span class="string">&quot;ATL&quot;</span>,<span class="string">&quot;JFK&quot;</span>,<span class="string">&quot;ATL&quot;</span>,<span class="string">&quot;SFO&quot;</span>]。但是它自然排序更大更靠后。</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>欧拉回路，一笔画，后序遍历，先尝试完所有的子节点最后在添加当前节点，确保死胡同会被首先加入，这样res中就保持了答案的逆序</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="comment">//欧拉回路，一笔画问题</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">findItinerary</span><span class="params">(tickets [][]<span class="keyword">string</span>)</span> []<span class="title">string</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> adj = <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">string</span>][]<span class="keyword">string</span>)</span><br><span class="line">    <span class="keyword">for</span> _, tick := <span class="keyword">range</span> tickets &#123;</span><br><span class="line">        adj[tick[<span class="number">0</span>]] = <span class="built_in">append</span>(adj[tick[<span class="number">0</span>]], tick[<span class="number">1</span>])</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> _, toList := <span class="keyword">range</span> adj &#123;</span><br><span class="line">        sort.Strings(toList)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> res []<span class="keyword">string</span></span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span> <span class="params">(cur <span class="keyword">string</span>)</span></span> </span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span> <span class="params">(cur <span class="keyword">string</span>)</span></span> &#123;</span><br><span class="line">        <span class="keyword">for</span> <span class="built_in">len</span>(adj[cur]) != <span class="number">0</span> &#123;</span><br><span class="line">            <span class="comment">//删除节点，避免重复访问</span></span><br><span class="line">            to := adj[cur][<span class="number">0</span>]</span><br><span class="line">            adj[cur] = adj[cur][<span class="number">1</span>:]</span><br><span class="line">            dfs(to)</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//后序遍历，最后将路径添加进去，保证死胡同会首先加入</span></span><br><span class="line">        res = <span class="built_in">append</span>(res, cur)</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(<span class="string">&quot;JFK&quot;</span>)</span><br><span class="line">    <span class="comment">//翻转下</span></span><br><span class="line">    <span class="keyword">for</span> i, j := <span class="number">0</span>, <span class="built_in">len</span>(res)<span class="number">-1</span>; i &lt; j; i, j = i+<span class="number">1</span>, j<span class="number">-1</span> &#123;</span><br><span class="line">        res[i], res[j] = res[j], res[i]</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="841-钥匙和房间"><a href="#841-钥匙和房间" class="headerlink" title="841. 钥匙和房间"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/keys-and-rooms/" >841. 钥匙和房间<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>中等</strong></p>
<p>有 <code>N</code> 个房间，开始时你位于 <code>0</code> 号房间。每个房间有不同的号码：<code>0，1，2，...，N-1</code>，并且房间里可能有一些钥匙能使你进入下一个房间。</p>
<p>在形式上，对于每个房间 <code>i</code> 都有一个钥匙列表 <code>rooms[i]</code>，每个钥匙 <code>rooms[i][j]</code> 由 <code>[0,1，...，N-1]</code> 中的一个整数表示，其中 <code>N = rooms.length</code>。 钥匙 <code>rooms[i][j] = v</code> 可以打开编号为 <code>v</code> 的房间。</p>
<p>最初，除 <code>0</code> 号房间外的其余所有房间都被锁住。</p>
<p>你可以自由地在房间之间来回走动。</p>
<p>如果能进入每个房间返回 <code>true</code>，否则返回 <code>false</code>。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入: [[<span class="number">1</span>],[<span class="number">2</span>],[<span class="number">3</span>],[]]</span><br><span class="line">输出: <span class="literal">true</span></span><br><span class="line">解释:  </span><br><span class="line">我们从 <span class="number">0</span> 号房间开始，拿到钥匙 <span class="number">1</span>。</span><br><span class="line">之后我们去 <span class="number">1</span> 号房间，拿到钥匙 <span class="number">2</span>。</span><br><span class="line">然后我们去 <span class="number">2</span> 号房间，拿到钥匙 <span class="number">3</span>。</span><br><span class="line">最后我们去了 <span class="number">3</span> 号房间。</span><br><span class="line">由于我们能够进入每个房间，我们返回 <span class="literal">true</span>。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：[[<span class="number">1</span>,<span class="number">3</span>],[<span class="number">3</span>,<span class="number">0</span>,<span class="number">1</span>],[<span class="number">2</span>],[<span class="number">0</span>]]</span><br><span class="line">输出：<span class="literal">false</span></span><br><span class="line">解释：我们不能进入 <span class="number">2</span> 号房间。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li> <code>1 &lt;= rooms.length &lt;= 1000</code></li>
<li> <code>0 &lt;= rooms[i].length &lt;= 1000</code></li>
<li> 所有房间中的钥匙数量总计不超过 <code>3000</code>。</li>
</ol>
<p><strong>解法一</strong></p>
<p>没啥好说的</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">canVisitAllRooms</span><span class="params">(rooms [][]<span class="keyword">int</span>)</span> <span class="title">bool</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> n = <span class="built_in">len</span>(rooms)</span><br><span class="line">    <span class="keyword">var</span> visit = <span class="built_in">make</span>([]<span class="keyword">bool</span>, n)</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(<span class="keyword">int</span>)</span></span></span><br><span class="line">    <span class="keyword">var</span> count = <span class="number">0</span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(idx <span class="keyword">int</span>)</span></span> &#123;</span><br><span class="line">        visit[idx] = <span class="literal">true</span></span><br><span class="line">        count++</span><br><span class="line">        <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="built_in">len</span>(rooms[idx]); i++ &#123;</span><br><span class="line">            <span class="keyword">if</span> !visit[rooms[idx][i]] &#123;</span><br><span class="line">                dfs(rooms[idx][i])   </span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(<span class="number">0</span>)</span><br><span class="line">    <span class="keyword">return</span> count == n</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="分治"><a href="#分治" class="headerlink" title="分治"></a><em>分治</em></h2><p>开个新坑，其实分治这个tag挺大的，很多题的做法都属于分治，而且涉及到分治的题目一般都还是有点难度的，不容易直接想出来</p>
<h2 id="241-为运算表达式设计优先级"><a href="#241-为运算表达式设计优先级" class="headerlink" title="241. 为运算表达式设计优先级"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/different-ways-to-add-parentheses/" >241. 为运算表达式设计优先级<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个含有数字和运算符的字符串，为表达式添加括号，改变其运算优先级以求出不同的结果。你需要给出所有可能的组合的结果。有效的运算符号包含 +, - 以及 * 。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="string">&quot;2-1-1&quot;</span></span><br><span class="line">输出: [<span class="number">0</span>, <span class="number">2</span>]</span><br><span class="line">解释: </span><br><span class="line">((<span class="number">2</span>-<span class="number">1</span>)-<span class="number">1</span>) = <span class="number">0</span> </span><br><span class="line">(<span class="number">2</span>-(<span class="number">1</span>-<span class="number">1</span>)) = <span class="number">2</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="string">&quot;2*3-4*5&quot;</span></span><br><span class="line">输出: [-<span class="number">34</span>, -<span class="number">14</span>, -<span class="number">10</span>, -<span class="number">10</span>, <span class="number">10</span>]</span><br><span class="line">解释: </span><br><span class="line">(<span class="number">2</span>*(<span class="number">3</span>-(<span class="number">4</span>*<span class="number">5</span>))) = -<span class="number">34</span> </span><br><span class="line">((<span class="number">2</span>*<span class="number">3</span>)-(<span class="number">4</span>*<span class="number">5</span>)) = -<span class="number">14</span> </span><br><span class="line">((<span class="number">2</span>*(<span class="number">3</span>-<span class="number">4</span>))*<span class="number">5</span>) = -<span class="number">10</span> </span><br><span class="line">(<span class="number">2</span>*((<span class="number">3</span>-<span class="number">4</span>)*<span class="number">5</span>)) = -<span class="number">10</span> </span><br><span class="line">(((<span class="number">2</span>*<span class="number">3</span>)-<span class="number">4</span>)*<span class="number">5</span>) = <span class="number">10</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>这题咋说呢，应该不算是回溯，是在分治tag中找的一题，还是挺有意思的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> Map&lt;String,List&lt;Integer&gt;&gt; map=<span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="comment">//分治</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">diffWaysToCompute</span><span class="params">(String input)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (input==<span class="keyword">null</span> || input.length()&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> diffWaysToCompute(input,<span class="number">0</span>,input.length()-<span class="number">1</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">diffWaysToCompute</span><span class="params">(String input,<span class="keyword">int</span> left,<span class="keyword">int</span> right)</span> </span>&#123;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    <span class="comment">/*if (left==right) &#123; //这一步可以去掉,最开始没考虑多位数的情况(考虑到了不知道怎么处理)</span></span><br><span class="line"><span class="comment">            res.add(Integer.valueOf(input.charAt(left))-48);</span></span><br><span class="line"><span class="comment">            return res;</span></span><br><span class="line"><span class="comment">        &#125;*/</span></span><br><span class="line">    String key=input.substring(left,right+<span class="number">1</span>);</span><br><span class="line">    <span class="keyword">if</span> (map.containsKey(key)) &#123;</span><br><span class="line">        <span class="keyword">return</span> map.get(key);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=left;i&lt;=right;i++) &#123; <span class="comment">//大意了,这里一开始写成了input.length...</span></span><br><span class="line">        <span class="keyword">char</span> c=input.charAt(i);</span><br><span class="line">        <span class="keyword">if</span> (c&lt;<span class="string">&#x27;0&#x27;</span>) &#123;</span><br><span class="line">            List&lt;Integer&gt; leftCompute=diffWaysToCompute(input,left,i-<span class="number">1</span>);</span><br><span class="line">            List&lt;Integer&gt; rightCompute=diffWaysToCompute(input,i+<span class="number">1</span>,right);</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> lc:leftCompute) &#123;</span><br><span class="line">                <span class="keyword">for</span> (<span class="keyword">int</span> rc:rightCompute) &#123;</span><br><span class="line">                    <span class="keyword">if</span> (c==<span class="string">&#x27;+&#x27;</span>) </span><br><span class="line">                        res.add(lc+rc);</span><br><span class="line">                    <span class="keyword">if</span> (c==<span class="string">&#x27;-&#x27;</span>) </span><br><span class="line">                        res.add(lc-rc);</span><br><span class="line">                    <span class="keyword">if</span> (c==<span class="string">&#x27;*&#x27;</span>) </span><br><span class="line">                        res.add(lc*rc);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (res.isEmpty()) &#123;</span><br><span class="line">        res.add(Integer.valueOf(key));</span><br><span class="line">    &#125;</span><br><span class="line">    map.put(key,res);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>第一天看了这道题，没想到思路，然后瞄了一眼评论区，看到了关键点，找到运算符，然后左右分别递归，没看到细节，第二天回忆了下思路写出了解，其实这题可以参考<a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/unique-binary-search-trees-ii/" >95. 不同的二叉搜索树 II<i class="fas fa-external-link-alt"></i></a> 我在我的 <a href="http://imlgw.top/2019/11/06/leetcode-er-cha-shu/">二叉树专题</a> 中也加了这道题，两者解法极为相似</p>
<h2 id="395-至少有K个重复字符的最长子串"><a href="#395-至少有K个重复字符的最长子串" class="headerlink" title="395. 至少有K个重复字符的最长子串"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/longest-substring-with-at-least-k-repeating-characters/" >395. 至少有K个重复字符的最长子串<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>中等</strong></p>
<p>找到给定字符串（由小写字符组成）中的最长子串<code>T</code>， 要求 <code>T</code> 中的每一字符出现次数都不少于 <code>k</code> 。输出 <code>T</code>的长度。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">s = <span class="string">&quot;aaabb&quot;</span>, k = <span class="number">3</span></span><br><span class="line"></span><br><span class="line">输出:</span><br><span class="line"><span class="number">3</span></span><br><span class="line"></span><br><span class="line">最长子串为 <span class="string">&quot;aaa&quot;</span> ，其中 <span class="string">&#x27;a&#x27;</span> 重复了 <span class="number">3</span> 次。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">s = <span class="string">&quot;ababbc&quot;</span>, k = <span class="number">2</span></span><br><span class="line"></span><br><span class="line">输出:</span><br><span class="line"><span class="number">5</span></span><br><span class="line"></span><br><span class="line">最长子串为 <span class="string">&quot;ababb&quot;</span> ，其中 <span class="string">&#x27;a&#x27;</span> 重复了 <span class="number">2</span> 次， <span class="string">&#x27;b&#x27;</span> 重复了 <span class="number">3</span> 次。</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>以出现次数最少的字符为中点分治，但是效率感人，380ms+</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">longestSubstring</span><span class="params">(String s, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (s == <span class="keyword">null</span> || s.length() == <span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span>[] count = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">26</span>];</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; s.length(); i++)&#123;</span><br><span class="line">        count[s.charAt(i)-<span class="string">&#x27;a&#x27;</span>]++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> min = <span class="number">0</span>; <span class="comment">//记录count最小的index</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>;i &lt; s.length(); i++)&#123;</span><br><span class="line">        min = count[s.charAt(i)-<span class="string">&#x27;a&#x27;</span>] &lt; count[s.charAt(min)-<span class="string">&#x27;a&#x27;</span>] ? i : min;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (count[s.charAt(min)-<span class="string">&#x27;a&#x27;</span>] &gt;= k) &#123;</span><br><span class="line">        <span class="keyword">return</span> s.length();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> Math.max(longestSubstring(s.substring(<span class="number">0</span>,min),k),longestSubstring(s.substring(min+<span class="number">1</span>),k));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>参考了题解区大佬们的剪枝和优化方法，循环以每个小于k的字符为结尾，分割字符，多路分治，大大降低分治递归树的高度</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//1ms 多路分治，虽然过了，但是感觉还是有点不流畅</span></span><br><span class="line"><span class="comment">//主要就是最后那个当以大于k的字符结尾的时候的额外处理，如果不wa一发不容易发现</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">longestSubstring</span><span class="params">(String s, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (s == <span class="keyword">null</span> || s.length() == <span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span>[] count = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">26</span>];</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; s.length(); i++)&#123;</span><br><span class="line">        count[s.charAt(i)-<span class="string">&#x27;a&#x27;</span>]++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> left = <span class="number">0</span>; <span class="comment">//分治左端点</span></span><br><span class="line">    <span class="keyword">boolean</span> flag = <span class="keyword">false</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; s.length(); i++)&#123;</span><br><span class="line">        <span class="keyword">if</span>(count[s.charAt(i)-<span class="string">&#x27;a&#x27;</span>] &lt; k)&#123;</span><br><span class="line">            flag = <span class="keyword">true</span>;</span><br><span class="line">            <span class="keyword">if</span>(i - left &gt;= res)&#123; <span class="comment">//剪枝优化</span></span><br><span class="line">                res = Math.max(longestSubstring(s.substring(left,i),k),res);</span><br><span class="line">            &#125;</span><br><span class="line">            left = i+<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(!flag) <span class="keyword">return</span> s.length();</span><br><span class="line">    <span class="comment">//上面分治的逻辑是以left到小于k的字母i进行分治，但是如果字符不是以小于k的字母结尾就无法计算</span></span><br><span class="line">    <span class="comment">//eg: aabbb k=3</span></span><br><span class="line">    <span class="keyword">return</span> Math.max(res,longestSubstring(s.substring(left),k));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>其实还要很多分治的方法，但是感觉都大同小异</p>

        </div>

        
            <div class="post-copyright-info">
                <div class="article-copyright-info-container">
    <ul>
        <li>本文标题：LeetCode回溯&amp;递归</li>
        <li>本文作者：Resolmi</li>
        <li>创建时间：2019-10-10 00:00:00</li>
        <li>
            本文链接：https://imlgw.top/2019/10/10/26679fc/
        </li>
        <li>
            版权声明：本博客所有文章除特别声明外，均采用 <a class="license" target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh">BY-NC-SA</a> 许可协议。转载请注明出处！
        </li>
    </ul>
</div>

            </div>
        

        
            <div class="article-nav">
                
                    <div class="article-prev">
                        <a class="prev"
                           rel="prev"
                           href="/2019/11/06/43c532c9/"
                        >
                            <span class="left arrow-icon flex-center">
                              <i class="fas fa-chevron-left"></i>
                            </span>
                            <span class="title flex-center">
                                <span class="post-nav-title-item">LeetCode二叉树</span>
                                <span class="post-nav-item">上一篇</span>
                            </span>
                        </a>
                    </div>
                
                
                    <div class="article-next">
                        <a class="next"
                           rel="next"
                           href="/2019/10/01/627d9e22/"
                        >
                            <span class="title flex-center">
                                <span class="post-nav-title-item">LeetCode栈&amp;队列</span>
                                <span class="post-nav-item">下一篇</span>
                            </span>
                            <span class="right arrow-icon flex-center">
                              <i class="fas fa-chevron-right"></i>
                            </span>
                        </a>
                    </div>
                
            </div>
        

        
            <div class="comment-container">
                <div class="comments-container">
    <div id="comment-anchor"></div>
    <div class="comment-area-title">
        <i class="fas fa-comments">&nbsp;评论</i>
    </div>
    

        
            <section class="disqus-comments">
<div id="disqus_thread">
  <noscript>Please enable JavaScript to view the <a target="_blank" rel="noopener" href="//disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
</div>
</section>

<script>
var disqus_shortname = 'imlgw';

var disqus_url = 'https://imlgw.top/2019/10/10/26679fc/';

(function(){
  var dsq = document.createElement('script');
  dsq.type = 'text/javascript';
  dsq.async = true;
  dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>

<script id="dsq-count-scr" src="//imlgw.disqus.com/count.js" async></script>
        
    
</div>

            </div>
        
    </div>
</div>


                
            </div>

        </div>

        <div class="page-main-content-bottom">
            <footer class="footer">
    <div class="info-container">
        <div class="copyright-info info-item">
            &copy;
            
              <span>2018</span>&nbsp;-&nbsp;
            
            2021&nbsp;<i class="fas fa-heart icon-animate"></i>&nbsp;<a href="/">Resolmi</a>
        </div>
        
            <script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
            <div class="website-count info-item">
                
                    <span id="busuanzi_container_site_uv">
                        访问人数&nbsp;<span id="busuanzi_value_site_uv"></span>&ensp;
                    </span>
                
                
                    <span id="busuanzi_container_site_pv">
                        总访问量&nbsp;<span id="busuanzi_value_site_pv"></span>
                    </span>
                
            </div>
        
        
            <div class="icp-info info-item"><a target="_blank" rel="nofollow" href="https://beian.miit.gov.cn">鄂ICP备18011208号</a></div>
        
    </div>
</footer>

        </div>
    </div>

    
        <div class="post-tools">
            <div class="post-tools-container">
    <ul class="tools-list">
        <!-- TOC aside toggle -->
        
            <li class="tools-item page-aside-toggle">
                <i class="fas fa-outdent"></i>
            </li>
        

        <!-- go comment -->
        
            <li class="go-comment">
                <i class="fas fa-comment"></i>
            </li>
        
    </ul>
</div>

        </div>
    

    <div class="right-bottom-side-tools">
        <div class="side-tools-container">
    <ul class="side-tools-list">
        <li class="tools-item tool-font-adjust-plus flex-center">
            <i class="fas fa-search-plus"></i>
        </li>

        <li class="tools-item tool-font-adjust-minus flex-center">
            <i class="fas fa-search-minus"></i>
        </li>

        <li class="tools-item tool-expand-width flex-center">
            <i class="fas fa-arrows-alt-h"></i>
        </li>

        <li class="tools-item tool-dark-light-toggle flex-center">
            <i class="fas fa-moon"></i>
        </li>

        <!-- rss -->
        

        

        <li class="tools-item tool-scroll-to-bottom flex-center">
            <i class="fas fa-arrow-down"></i>
        </li>
    </ul>

    <ul class="exposed-tools-list">
        <li class="tools-item tool-toggle-show flex-center">
            <i class="fas fa-cog fa-spin"></i>
        </li>
        
            <li class="tools-item tool-scroll-to-top flex-center">
                <i class="arrow-up fas fa-arrow-up"></i>
                <span class="percent"></span>
            </li>
        
    </ul>
</div>

    </div>

    
        <aside class="page-aside">
            <div class="post-toc-wrap">
    <div class="post-toc">
        <ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#17-%E7%94%B5%E8%AF%9D%E5%8F%B7%E7%A0%81%E7%9A%84%E5%AD%97%E6%AF%8D%E7%BB%84%E5%90%88"><span class="nav-number">1.</span> <span class="nav-text">17. 电话号码的字母组合</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#93-%E5%A4%8D%E5%8E%9FIP%E5%9C%B0%E5%9D%80"><span class="nav-number">2.</span> <span class="nav-text">93. 复原IP地址</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#131-%E5%88%86%E5%89%B2%E5%9B%9E%E6%96%87%E4%B8%B2"><span class="nav-number">3.</span> <span class="nav-text">131. 分割回文串</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#46-%E5%85%A8%E6%8E%92%E5%88%97"><span class="nav-number">4.</span> <span class="nav-text">46. 全排列</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#60-%E7%AC%ACk%E4%B8%AA%E6%8E%92%E5%88%97"><span class="nav-number">5.</span> <span class="nav-text">60. 第k个排列</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5374-%E9%95%BF%E5%BA%A6%E4%B8%BA-n-%E7%9A%84%E5%BC%80%E5%BF%83%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E5%AD%97%E5%85%B8%E5%BA%8F%E7%AC%AC-k-%E5%B0%8F%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2"><span class="nav-number">6.</span> <span class="nav-text">5374. 长度为 n 的开心字符串中字典序第 k 小的字符串</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#47-%E5%85%A8%E6%8E%92%E5%88%97-II"><span class="nav-number">7.</span> <span class="nav-text">47. 全排列 II</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Bug%E8%AD%A6%E5%91%8A"><span class="nav-number">7.1.</span> <span class="nav-text">Bug警告</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1286-%E5%AD%97%E6%AF%8D%E7%BB%84%E5%90%88%E8%BF%AD%E4%BB%A3%E5%99%A8"><span class="nav-number">8.</span> <span class="nav-text">1286. 字母组合迭代器</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#77-%E7%BB%84%E5%90%88"><span class="nav-number">9.</span> <span class="nav-text">77. 组合</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#39-%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8C"><span class="nav-number">10.</span> <span class="nav-text">39. 组合总和</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#40-%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8C-II"><span class="nav-number">11.</span> <span class="nav-text">40. 组合总和 II</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#216-%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8C-III"><span class="nav-number">12.</span> <span class="nav-text">216. 组合总和 III</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#78-%E5%AD%90%E9%9B%86"><span class="nav-number">13.</span> <span class="nav-text">78. 子集</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#90-%E5%AD%90%E9%9B%86-II"><span class="nav-number">14.</span> <span class="nav-text">90. 子集 II</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#357-%E8%AE%A1%E7%AE%97%E5%90%84%E4%B8%AA%E4%BD%8D%E6%95%B0%E4%B8%8D%E5%90%8C%E7%9A%84%E6%95%B0%E5%AD%97%E4%B8%AA%E6%95%B0"><span class="nav-number">15.</span> <span class="nav-text">357. 计算各个位数不同的数字个数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#89-%E6%A0%BC%E9%9B%B7%E7%BC%96%E7%A0%81"><span class="nav-number">16.</span> <span class="nav-text">89. 格雷编码</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#526-%E4%BC%98%E7%BE%8E%E7%9A%84%E6%8E%92%E5%88%97"><span class="nav-number">17.</span> <span class="nav-text">526. 优美的排列</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#784-%E5%AD%97%E6%AF%8D%E5%A4%A7%E5%B0%8F%E5%86%99%E5%85%A8%E6%8E%92%E5%88%97"><span class="nav-number">18.</span> <span class="nav-text">784. 字母大小写全排列</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1079-%E6%B4%BB%E5%AD%97%E5%8D%B0%E5%88%B7"><span class="nav-number">19.</span> <span class="nav-text">1079. 活字印刷</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Bug%E8%AD%A6%E5%91%8A%EF%BC%81%EF%BC%81%EF%BC%81"><span class="nav-number">19.1.</span> <span class="nav-text">Bug警告！！！</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1291-%E9%A1%BA%E6%AC%A1%E6%95%B0"><span class="nav-number">20.</span> <span class="nav-text">1291. 顺次数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#22-%E6%8B%AC%E5%8F%B7%E7%94%9F%E6%88%90"><span class="nav-number">21.</span> <span class="nav-text">22. 括号生成</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#306-%E7%B4%AF%E5%8A%A0%E6%95%B0"><span class="nav-number">22.</span> <span class="nav-text">306. 累加数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#842-%E5%B0%86%E6%95%B0%E7%BB%84%E6%8B%86%E5%88%86%E6%88%90%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E5%BA%8F%E5%88%97"><span class="nav-number">23.</span> <span class="nav-text">842. 将数组拆分成斐波那契序列</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#139-%E5%8D%95%E8%AF%8D%E6%8B%86%E5%88%86"><span class="nav-number">24.</span> <span class="nav-text">139. 单词拆分</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#140-%E5%8D%95%E8%AF%8D%E6%8B%86%E5%88%86-II"><span class="nav-number">25.</span> <span class="nav-text">140. 单词拆分 II</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#473-%E7%81%AB%E6%9F%B4%E6%8B%BC%E6%AD%A3%E6%96%B9%E5%BD%A2"><span class="nav-number">26.</span> <span class="nav-text">473. 火柴拼正方形</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#698-%E5%88%92%E5%88%86%E4%B8%BAk%E4%B8%AA%E7%9B%B8%E7%AD%89%E7%9A%84%E5%AD%90%E9%9B%86"><span class="nav-number">27.</span> <span class="nav-text">698. 划分为k个相等的子集</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#491-%E9%80%92%E5%A2%9E%E5%AD%90%E5%BA%8F%E5%88%97"><span class="nav-number">28.</span> <span class="nav-text">491. 递增子序列</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#679-24-%E7%82%B9%E6%B8%B8%E6%88%8F"><span class="nav-number">29.</span> <span class="nav-text">679. 24 点游戏</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5526-%E6%9C%80%E5%A4%9A%E5%8F%AF%E8%BE%BE%E6%88%90%E7%9A%84%E6%8D%A2%E6%A5%BC%E8%AF%B7%E6%B1%82%E6%95%B0%E7%9B%AE"><span class="nav-number">30.</span> <span class="nav-text">5526. 最多可达成的换楼请求数目</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BA%8C%E7%BB%B4%E5%B9%B3%E9%9D%A2%E4%B8%8A%E7%9A%84%E5%9B%9E%E6%BA%AF"><span class="nav-number">31.</span> <span class="nav-text">二维平面上的回溯</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#79-%E5%8D%95%E8%AF%8D%E6%90%9C%E7%B4%A2"><span class="nav-number">32.</span> <span class="nav-text">79. 单词搜索</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#200-%E5%B2%9B%E5%B1%BF%E6%95%B0%E9%87%8F"><span class="nav-number">33.</span> <span class="nav-text">200. 岛屿数量</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#130-%E8%A2%AB%E5%9B%B4%E7%BB%95%E7%9A%84%E5%8C%BA%E5%9F%9F"><span class="nav-number">34.</span> <span class="nav-text">130. 被围绕的区域</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#417-%E5%A4%AA%E5%B9%B3%E6%B4%8B%E5%A4%A7%E8%A5%BF%E6%B4%8B%E6%B0%B4%E6%B5%81%E9%97%AE%E9%A2%98"><span class="nav-number">35.</span> <span class="nav-text">417. 太平洋大西洋水流问题</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#51-N%E7%9A%87%E5%90%8E"><span class="nav-number">36.</span> <span class="nav-text">51. N皇后</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#52-N%E7%9A%87%E5%90%8E-II"><span class="nav-number">37.</span> <span class="nav-text">52. N皇后 II</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#37-%E8%A7%A3%E6%95%B0%E7%8B%AC"><span class="nav-number">38.</span> <span class="nav-text">37. 解数独</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#529-%E6%89%AB%E9%9B%B7%E6%B8%B8%E6%88%8F"><span class="nav-number">39.</span> <span class="nav-text">529. 扫雷游戏</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#695-%E5%B2%9B%E5%B1%BF%E7%9A%84%E6%9C%80%E5%A4%A7%E9%9D%A2%E7%A7%AF"><span class="nav-number">40.</span> <span class="nav-text">695. 岛屿的最大面积</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#547-%E6%9C%8B%E5%8F%8B%E5%9C%88"><span class="nav-number">41.</span> <span class="nav-text">547. 朋友圈</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1219-%E9%BB%84%E9%87%91%E7%9F%BF%E5%B7%A5"><span class="nav-number">42.</span> <span class="nav-text">1219. 黄金矿工</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%9D%A2%E8%AF%95%E9%A2%9813-%E6%9C%BA%E5%99%A8%E4%BA%BA%E7%9A%84%E8%BF%90%E5%8A%A8%E8%8C%83%E5%9B%B4"><span class="nav-number">43.</span> <span class="nav-text">面试题13. 机器人的运动范围</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1020-%E9%A3%9E%E5%9C%B0%E7%9A%84%E6%95%B0%E9%87%8F"><span class="nav-number">44.</span> <span class="nav-text">1020. 飞地的数量</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#934-%E6%9C%80%E7%9F%AD%E7%9A%84%E6%A1%A5"><span class="nav-number">45.</span> <span class="nav-text">934. 最短的桥</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#733-%E5%9B%BE%E5%83%8F%E6%B8%B2%E6%9F%93"><span class="nav-number">46.</span> <span class="nav-text">733. 图像渲染</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1559-%E4%BA%8C%E7%BB%B4%E7%BD%91%E6%A0%BC%E5%9B%BE%E4%B8%AD%E6%8E%A2%E6%B5%8B%E7%8E%AF"><span class="nav-number">47.</span> <span class="nav-text">1559. 二维网格图中探测环</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#332-%E9%87%8D%E6%96%B0%E5%AE%89%E6%8E%92%E8%A1%8C%E7%A8%8B"><span class="nav-number">48.</span> <span class="nav-text">332. 重新安排行程</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#841-%E9%92%A5%E5%8C%99%E5%92%8C%E6%88%BF%E9%97%B4"><span class="nav-number">49.</span> <span class="nav-text">841. 钥匙和房间</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%88%86%E6%B2%BB"><span class="nav-number">50.</span> <span class="nav-text">分治</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#241-%E4%B8%BA%E8%BF%90%E7%AE%97%E8%A1%A8%E8%BE%BE%E5%BC%8F%E8%AE%BE%E8%AE%A1%E4%BC%98%E5%85%88%E7%BA%A7"><span class="nav-number">51.</span> <span class="nav-text">241. 为运算表达式设计优先级</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#395-%E8%87%B3%E5%B0%91%E6%9C%89K%E4%B8%AA%E9%87%8D%E5%A4%8D%E5%AD%97%E7%AC%A6%E7%9A%84%E6%9C%80%E9%95%BF%E5%AD%90%E4%B8%B2"><span class="nav-number">52.</span> <span class="nav-text">395. 至少有K个重复字符的最长子串</span></a></li></ol>
    </div>
</div>
        </aside>
    

    <div class="image-viewer-container">
    <img src="">
</div>


    
        <div class="search-pop-overlay">
    <div class="popup search-popup">
        <div class="search-header">
          <span class="search-input-field-pre">
            <i class="fas fa-keyboard"></i>
          </span>
            <div class="search-input-container">
                <input autocomplete="off"
                       autocorrect="off"
                       autocapitalize="off"
                       placeholder="搜索..."
                       spellcheck="false"
                       type="search"
                       class="search-input"
                >
            </div>
            <span class="popup-btn-close">
                <i class="fas fa-times"></i>
            </span>
        </div>
        <div id="search-result">
            <div id="no-result">
                <i class="fas fa-spinner fa-pulse fa-5x fa-fw"></i>
            </div>
        </div>
    </div>
</div>

    

</main>



<script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/utils.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/main.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/header-shrink.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/back2top.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/dark-light-toggle.js"></script>


    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/local-search.js"></script>



    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/code-copy.js"></script>



    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/lazyload.js"></script>


<div class="post-scripts pjax">
    
        <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/left-side-toggle.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/libs/anime.min.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/toc.js"></script>
    
</div>


    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/libs/pjax.min.js"></script>
<script>
    window.addEventListener('DOMContentLoaded', () => {
        window.pjax = new Pjax({
            selectors: [
                'head title',
                '.page-container',
                '.pjax'
            ],
            history: true,
            debug: false,
            cacheBust: false,
            timeout: 0,
            analytics: false,
            currentUrlFullReload: false,
            scrollRestoration: false,
            // scrollTo: true,
        });

        document.addEventListener('pjax:send', () => {
            KEEP.utils.pjaxProgressBarStart();
        });

        document.addEventListener('pjax:complete', () => {
            KEEP.utils.pjaxProgressBarEnd();
            window.pjax.executeScripts(document.querySelectorAll('script[data-pjax], .pjax script'));
            KEEP.refresh();
        });
    });
</script>



<script src="https://cdn.jsdelivr.net/npm/live2d-widget@3.x/lib/L2Dwidget.min.js"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","tagMode":false,"debug":false,"model":{"jsonPath":"https://cdn.jsdelivr.net/npm/live2d-widget-model-hijiki@1.0.5/assets/hijiki.model.json"},"display":{"superSample":2,"width":160,"height":320,"position":"right","hOffset":0,"vOffset":-70},"mobile":{"show":false,"scale":0.2},"log":false});</script></body>
</html>
